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
115
116
117
118
119
120
121
122
123
124
// 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::{
    dtos::MessageDto,
    responses::{MessageChildrenResponse, MessageMetadataResponse as MessageMetadata, 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";
        #[derive(Debug, Serialize, Deserialize)]
        struct ResponseWrapper {
            data: MessagesFindResponse,
        }
        let resp: ResponseWrapper = 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);
        #[derive(Debug, Serialize, Deserialize)]
        struct ResponseWrapper {
            data: MessageDto,
        }
        let resp: ResponseWrapper = self
            .client
            .node_manager
            .get_request(path, None, self.client.get_timeout(Api::GetMessage))
            .await?;

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

    /// 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/{}/metadata", message_id);
        #[derive(Debug, Serialize, Deserialize)]
        struct ResponseWrapper {
            data: MessageMetadata,
        }
        let resp: ResponseWrapper = 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/{}/raw", message_id);
        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/{}/children", message_id);
        #[derive(Debug, Serialize, Deserialize)]
        struct ResponseWrapper {
            data: MessageChildrenResponse,
        }
        let resp: ResponseWrapper = 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]>>>()
    }
}