tomsg_rs/
message.rs

1use std::convert::TryFrom;
2use std::convert::TryInto;
3use std::time;
4
5use crate::id::Id;
6use crate::line::Line;
7use crate::word::Word;
8
9/// A tomsg message message in a room.
10#[derive(Debug, Clone, PartialEq, Eq, Hash)]
11pub struct Message {
12    /// The ID of the message.
13    pub id: Id,
14    /// The ID of the message this message replies on, if any.
15    pub reply_on: Option<Id>,
16    /// The name of the tomsg room this message is sent in.
17    pub roomname: Box<Word>,
18    /// The username of the author of this message.
19    pub username: Box<Word>,
20    /// The time this message was sent.
21    pub timestamp: time::SystemTime,
22    /// The contents of this message.
23    pub message: Box<Line>,
24}
25
26impl Message {
27    pub(super) fn try_parse(words: &[&str]) -> Result<Self, String> {
28        let err = |field| format!("got invalid value for message field: {}", field);
29
30        macro_rules! parse {
31            ($val:expr, $type:ty, $field:expr) => {
32                $val.parse::<$type>().map_err(|_| err($field))?
33            };
34        }
35        let parse_id = |val, field| Id::try_from(val).map_err(|_| err(field));
36
37        let id = parse!(words[3], i64, "id");
38        let id = parse_id(id, "id")?;
39
40        let reply_on = match parse!(words[4], i64, "reply_on") {
41            -1 => None,
42            id => Some(parse_id(id, "reply_on")?),
43        };
44        let roomname = words[0].to_string().try_into()?;
45        let username = words[1].to_string().try_into()?;
46
47        let timestamp = parse!(words[2], u64, "timestamp");
48        let timestamp = time::UNIX_EPOCH + time::Duration::from_micros(timestamp);
49
50        let message = words[5..].join(" ");
51        let message = message.try_into()?;
52
53        Ok(Self {
54            id,
55            reply_on,
56            roomname,
57            username,
58            timestamp,
59            message,
60        })
61    }
62}