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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// Copyright 2021 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

use crate::{Api, Client, Result};
use bee_message::{Message, MessageId};
use bee_rest_api::types::{
    body::SuccessBody,
    responses::{
        MessageChildrenResponse, MessageMetadataResponse as MessageMetadata, MessageResponse, MessagesFindResponse,
    },
};

use std::convert::TryFrom;

/// Builder of GET /api/v1/messages/{messageId} endpoint
pub struct GetMessageBuilder<'a> {
    client: &'a Client,
}

impl<'a> GetMessageBuilder<'a> {
    /// Create GET /api/v1/messages endpoint builder
    pub fn new(client: &'a Client) -> Self {
        Self { client }
    }

    /// GET /api/v1/messages?index={Index} endpoint
    /// Consume the builder and search for messages matching the index
    pub async fn index<I: AsRef<[u8]>>(self, index: I) -> Result<Box<[MessageId]>> {
        let path = "api/v1/messages";

        let resp: SuccessBody<MessagesFindResponse> = self
            .client
            .node_manager
            .get_request(
                path,
                Some(&format!("index={}", hex::encode(index))),
                self.client.get_timeout(Api::GetMessage),
            )
            .await?;

        resp.data
            .message_ids
            .iter()
            .map(|s| {
                let mut message_id = [0u8; 32];
                hex::decode_to_slice(s, &mut message_id)?;
                Ok(MessageId::from(message_id))
            })
            .collect::<Result<Box<[MessageId]>>>()
    }

    /// GET /api/v1/messages/{messageID} endpoint
    /// Consume the builder and find a message by its identifer. This method returns the given message object.
    pub async fn data(self, message_id: &MessageId) -> Result<Message> {
        let path = &format!("api/v1/messages/{message_id}");

        let resp: SuccessBody<MessageResponse> = self
            .client
            .node_manager
            .get_request(path, None, self.client.get_timeout(Api::GetMessage))
            .await?;

        Ok(Message::try_from(&resp.data.0)?)
    }

    /// GET /api/v1/messages/{messageID}/metadata endpoint
    /// Consume the builder and find a message by its identifer. This method returns the given message metadata.
    pub async fn metadata(self, message_id: &MessageId) -> Result<MessageMetadata> {
        let path = &format!("api/v1/messages/{message_id}/metadata");

        let resp: SuccessBody<MessageMetadata> = self
            .client
            .node_manager
            .get_request(path, None, self.client.get_timeout(Api::GetMessage))
            .await?;

        Ok(resp.data)
    }

    /// GET /api/v1/messages/{messageID}/raw endpoint
    /// Consume the builder and find a message by its identifer. This method returns the given message raw data.
    pub async fn raw(self, message_id: &MessageId) -> Result<String> {
        let path = &format!("api/v1/messages/{message_id}/raw");
        let resp = self
            .client
            .node_manager
            .get_request_text(path, None, self.client.get_timeout(Api::GetMessage))
            .await?;

        Ok(resp)
    }

    /// GET /api/v1/messages/{messageID}/children endpoint
    /// Consume the builder and returns the list of message IDs that reference a message by its identifier.
    pub async fn children(self, message_id: &MessageId) -> Result<Box<[MessageId]>> {
        let path = &format!("api/v1/messages/{message_id}/children");

        let resp: SuccessBody<MessageChildrenResponse> = self
            .client
            .node_manager
            .get_request(path, None, self.client.get_timeout(Api::GetMessage))
            .await?;

        resp.data
            .children_message_ids
            .iter()
            .map(|s| {
                let mut message_id = [0u8; 32];
                hex::decode_to_slice(s, &mut message_id)?;
                Ok(MessageId::from(message_id))
            })
            .collect::<Result<Box<[MessageId]>>>()
    }
}