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
use slack::SlackText;
use types::SlackResult;
use hex::{HexColor, HexColorT};
use helper::opt_str_to_slacktext;

/// Slack allows for attachments to be added to messages. See
/// https://api.slack.com/docs/attachments for more information.
#[derive(RustcEncodable, Debug)]
pub struct Attachment {
    /// Required text for attachment.
    /// Slack will use this text to display on devices that don't support markup.
    pub fallback: SlackText,
    /// Optional text for other devices, markup supported
    pub text: Option<SlackText>,
    /// Optional text that appears above attachment
    pub pretext: Option<SlackText>,
    /// Color of attachment
    pub color: HexColor,
    /// Fields are defined as an array, and hashes contained within it will be
    /// displayed in a table inside the message attachment.
    pub fields: Option<Vec<Field>>,
}

/// Attachment template to simplify constructing attachments
/// for common use cases.
#[derive(Debug)]
pub enum AttachmentTemplate<'a> {
    /// Specify all attributes of attachment
    Complete {
        /// Required text for attachment.
        /// Slack will use this text to display on devices that don't support markup.
        fallback: &'a str,
        /// Optional primary text of attachment
        text: Option<&'a str>,
        /// Optional text that appears above attachment
        pretext: Option<&'a str>,
        /// Color string can be any hex code starting with #
        color: &'a str,
        /// Fields are defined as an array, and hashes contained within it will
        /// be displayed in a table inside the message attachment.
        fields: Option<Vec<Field>>,
    },
    /// Provide only text and color for attachment
    /// other values will be defaulted
    Text {
        /// Text to send
        text: &'a str,
        /// Color string can be any hex code starting with #
        color: &'a str,
    },
}

impl Attachment {
    /// Construct new attachment based on template provided
    pub fn new(t: AttachmentTemplate) -> SlackResult<Attachment> {
        match t {
            AttachmentTemplate::Complete { fallback, text, pretext, color, fields } => {
                let c = try!(HexColorT::new(color));
                Ok(Attachment {
                    fallback: SlackText::new(fallback),
                    text: opt_str_to_slacktext(&text),
                    pretext: opt_str_to_slacktext(&pretext),
                    color: c,
                    fields: fields,
                })
            }
            AttachmentTemplate::Text { text, color } => {
                let c = try!(HexColorT::new(color));
                Ok(Attachment {
                    fallback: SlackText::new(text),
                    text: Some(SlackText::new(text)),
                    pretext: None,
                    color: c,
                    fields: None,
                })
            }
        }
    }
}

/// Fields are defined as an array, and hashes contained within it will
/// be displayed in a table inside the message attachment.
#[derive(RustcEncodable, Debug)]
pub struct Field {
    /// Shown as a bold heading above the value text.
    /// It cannot contain markup and will be escaped for you.
    pub title: String,
    /// The text value of the field. It may contain standard message markup
    /// and must be escaped as normal. May be multi-line.
    pub value: SlackText,
    /// An optional flag indicating whether the value is short enough to be
    /// displayed side-by-side with other values.
    pub short: Option<bool>,
}

impl Field {
    /// Construct a new field
    pub fn new(title: &str, value: &str, short: Option<bool>) -> Field {
        Field {
            title: title.to_owned(),
            value: SlackText::new(value),
            short: short,
        }
    }
}