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
use crate::graph::NodeContents;
use crate::{Channel, Result, UrbitAPIError};

/// A struct that provides an interface for interacting with Urbit chats
pub struct Chat<'a> {
    pub channel: &'a mut Channel,
}

/// A struct that represents a message that is to be sent to an Urbit chat.
/// `Message` provides methods to build a message in chunks, thereby allowing you
/// to add content which needs to be parsed, for example links @p mentions.
/// It is technically an alias for the `NodeContents` struct.
// #[derive(Debug, Eq, Ord, PartialEq, PartialOrd)]
pub type Message = NodeContents;

/// A `Message` with the author @p also included
#[derive(Clone, Debug)]
pub struct AuthoredMessage {
    pub author: String,
    pub message: Message,
}

impl AuthoredMessage {
    /// Create a new `AuthoredMessage`
    pub fn new(author: String, message: Message) -> Self {
        AuthoredMessage {
            author: author,
            message: message,
        }
    }
}

/// Methods for interacting with a Chat
impl<'a> Chat<'a> {
    /// Send a message to an Urbit chat.
    /// Returns the index of the node that was added
    /// to Graph Store.
    pub fn send_message(
        &mut self,
        chat_ship: &str,
        chat_name: &str,
        message: &Message,
    ) -> Result<String> {
        let node = self.channel.graph_store().new_node(message);

        if let Ok(_) = self
            .channel
            .graph_store()
            .add_node(chat_ship, chat_name, &node)
        {
            Ok(node.index)
        } else {
            Err(UrbitAPIError::FailedToSendChatMessage(
                message.to_json().dump(),
            ))
        }
    }

    /// Extracts a Chat's messages automatically into a list of `String`s
    pub fn export_chat_log(&mut self, chat_ship: &str, chat_name: &str) -> Result<Vec<String>> {
        let chat_graph = &self.channel.graph_store().get_graph(chat_ship, chat_name)?;
        let mut export_log = vec![];

        let mut nodes = chat_graph.clone().nodes;
        nodes.sort_by(|a, b| a.time_sent.cmp(&b.time_sent));

        for node in nodes {
            if !node.contents.is_empty() {
                export_log.push(node.to_formatted_string());
            }
        }

        Ok(export_log)
    }
}