coap_lite/
response.rs

1use crate::{
2    header::{MessageClass, MessageType, ResponseType as Status},
3    packet::Packet,
4};
5
6/// The CoAP response.
7#[derive(Clone, Debug, PartialEq)]
8pub struct CoapResponse {
9    pub message: Packet,
10}
11
12impl CoapResponse {
13    /// Creates a new response.
14    pub fn new(request: &Packet) -> Option<CoapResponse> {
15        let mut packet = Packet::new();
16
17        packet.header.set_version(1);
18        let response_type = match request.header.get_type() {
19            MessageType::Confirmable => MessageType::Acknowledgement,
20            MessageType::NonConfirmable => MessageType::NonConfirmable,
21            _ => return None,
22        };
23        packet.header.set_type(response_type);
24        packet.header.code = MessageClass::Response(Status::Content);
25        packet.header.message_id = request.header.message_id;
26        packet.set_token(request.get_token().to_vec());
27
28        Some(CoapResponse { message: packet })
29    }
30
31    /// Sets the status.
32    pub fn set_status(&mut self, status: Status) {
33        self.message.header.code = MessageClass::Response(status);
34    }
35
36    /// Returns the status.
37    pub fn get_status(&self) -> &Status {
38        match self.message.header.code {
39            MessageClass::Response(Status::Created) => &Status::Created,
40            MessageClass::Response(Status::Deleted) => &Status::Deleted,
41            MessageClass::Response(Status::Valid) => &Status::Valid,
42            MessageClass::Response(Status::Changed) => &Status::Changed,
43            MessageClass::Response(Status::Content) => &Status::Content,
44
45            MessageClass::Response(Status::BadRequest) => &Status::BadRequest,
46            MessageClass::Response(Status::Unauthorized) => {
47                &Status::Unauthorized
48            }
49            MessageClass::Response(Status::BadOption) => &Status::BadOption,
50            MessageClass::Response(Status::Forbidden) => &Status::Forbidden,
51            MessageClass::Response(Status::NotFound) => &Status::NotFound,
52            MessageClass::Response(Status::MethodNotAllowed) => {
53                &Status::MethodNotAllowed
54            }
55            MessageClass::Response(Status::NotAcceptable) => {
56                &Status::NotAcceptable
57            }
58            MessageClass::Response(Status::PreconditionFailed) => {
59                &Status::PreconditionFailed
60            }
61            MessageClass::Response(Status::RequestEntityTooLarge) => {
62                &Status::RequestEntityTooLarge
63            }
64            MessageClass::Response(Status::UnsupportedContentFormat) => {
65                &Status::UnsupportedContentFormat
66            }
67
68            MessageClass::Response(Status::InternalServerError) => {
69                &Status::InternalServerError
70            }
71            MessageClass::Response(Status::NotImplemented) => {
72                &Status::NotImplemented
73            }
74            MessageClass::Response(Status::BadGateway) => &Status::BadGateway,
75            MessageClass::Response(Status::ServiceUnavailable) => {
76                &Status::ServiceUnavailable
77            }
78            MessageClass::Response(Status::GatewayTimeout) => {
79                &Status::GatewayTimeout
80            }
81            MessageClass::Response(Status::ProxyingNotSupported) => {
82                &Status::ProxyingNotSupported
83            }
84            _ => &Status::UnKnown,
85        }
86    }
87}
88
89#[cfg(test)]
90mod test {
91    use super::*;
92
93    #[test]
94    fn test_new_response_valid() {
95        for mtyp in [MessageType::Confirmable, MessageType::NonConfirmable] {
96            let mut packet = Packet::new();
97            packet.header.set_type(mtyp);
98            let opt_resp = CoapResponse::new(&packet);
99            assert!(opt_resp.is_some());
100
101            let response = opt_resp.unwrap();
102            assert_eq!(packet.payload, response.message.payload);
103        }
104    }
105
106    #[test]
107    fn test_new_response_invalid() {
108        let mut packet = Packet::new();
109        packet.header.set_type(MessageType::Acknowledgement);
110        assert!(CoapResponse::new(&packet).is_none());
111    }
112}