diff --git a/src/message.rs b/src/message.rs index 90bce3db..759b7d23 100644 --- a/src/message.rs +++ b/src/message.rs @@ -18,7 +18,7 @@ use ns; use stanza_error::StanzaError; use chatstates::ChatState; -use receipts::Receipt; +use receipts::{Request as ReceiptRequest, Received as ReceiptReceived}; use delay::Delay; use attention::Attention; use message_correct::Replace; @@ -31,7 +31,8 @@ use mam::Result_ as MamResult; pub enum MessagePayload { StanzaError(StanzaError), ChatState(ChatState), - Receipt(Receipt), + ReceiptRequest(ReceiptRequest), + ReceiptReceived(ReceiptReceived), Delay(Delay), Attention(Attention), MessageCorrect(Replace), @@ -58,8 +59,8 @@ impl TryFrom for MessagePayload { | ("gone", ns::CHATSTATES) => MessagePayload::ChatState(ChatState::try_from(elem)?), // XEP-0184 - ("request", ns::RECEIPTS) - | ("received", ns::RECEIPTS) => MessagePayload::Receipt(Receipt::try_from(elem)?), + ("request", ns::RECEIPTS) => MessagePayload::ReceiptRequest(ReceiptRequest::try_from(elem)?), + ("received", ns::RECEIPTS) => MessagePayload::ReceiptReceived(ReceiptReceived::try_from(elem)?), // XEP-0203 ("delay", ns::DELAY) => MessagePayload::Delay(Delay::try_from(elem)?), @@ -91,7 +92,8 @@ impl From for Element { MessagePayload::StanzaError(stanza_error) => stanza_error.into(), MessagePayload::Attention(attention) => attention.into(), MessagePayload::ChatState(chatstate) => chatstate.into(), - MessagePayload::Receipt(receipt) => receipt.into(), + MessagePayload::ReceiptRequest(request) => request.into(), + MessagePayload::ReceiptReceived(received) => received.into(), MessagePayload::Delay(delay) => delay.into(), MessagePayload::MessageCorrect(replace) => replace.into(), MessagePayload::ExplicitMessageEncryption(eme) => eme.into(), diff --git a/src/receipts.rs b/src/receipts.rs index 7c3625b8..6ccec7ea 100644 --- a/src/receipts.rs +++ b/src/receipts.rs @@ -13,46 +13,65 @@ use error::Error; use ns; #[derive(Debug, Clone)] -pub enum Receipt { - Request, - Received(Option), -} +pub struct Request; -impl TryFrom for Receipt { +impl TryFrom for Request { type Err = Error; - fn try_from(elem: Element) -> Result { + fn try_from(elem: Element) -> Result { + if !elem.is("request", ns::RECEIPTS) { + return Err(Error::ParseError("This is not a request element.")); + } for _ in elem.children() { - return Err(Error::ParseError("Unknown child in receipt element.")); + return Err(Error::ParseError("Unknown child in request element.")); } - if elem.is("request", ns::RECEIPTS) { - for _ in elem.attrs() { - return Err(Error::ParseError("Unknown attribute in request element.")); - } - Ok(Receipt::Request) - } else if elem.is("received", ns::RECEIPTS) { - for (attr, _) in elem.attrs() { - if attr != "id" { - return Err(Error::ParseError("Unknown attribute in received element.")); - } - } - let id = get_attr!(elem, "id", optional); - Ok(Receipt::Received(id)) - } else { - Err(Error::ParseError("This is not a receipt element.")) + for _ in elem.attrs() { + return Err(Error::ParseError("Unknown attribute in request element.")); } + Ok(Request) } } -impl From for Element { - fn from(receipt: Receipt) -> Element { - match receipt { - Receipt::Request => Element::builder("request") - .ns(ns::RECEIPTS), - Receipt::Received(id) => Element::builder("received") - .ns(ns::RECEIPTS) - .attr("id", id), - }.build() +impl From for Element { + fn from(_: Request) -> Element { + Element::builder("request") + .ns(ns::RECEIPTS) + .build() + } +} + +#[derive(Debug, Clone)] +pub struct Received { + pub id: Option, +} + +impl TryFrom for Received { + type Err = Error; + + fn try_from(elem: Element) -> Result { + if !elem.is("received", ns::RECEIPTS) { + return Err(Error::ParseError("This is not a received element.")); + } + for _ in elem.children() { + return Err(Error::ParseError("Unknown child in received element.")); + } + for (attr, _) in elem.attrs() { + if attr != "id" { + return Err(Error::ParseError("Unknown attribute in received element.")); + } + } + Ok(Received { + id: get_attr!(elem, "id", optional), + }) + } +} + +impl From for Element { + fn from(received: Received) -> Element { + Element::builder("received") + .ns(ns::RECEIPTS) + .attr("id", received.id) + .build() } } @@ -63,22 +82,25 @@ mod tests { #[test] fn test_simple() { let elem: Element = "".parse().unwrap(); - Receipt::try_from(elem).unwrap(); + Request::try_from(elem).unwrap(); let elem: Element = "".parse().unwrap(); - Receipt::try_from(elem).unwrap(); + Received::try_from(elem).unwrap(); let elem: Element = "".parse().unwrap(); - Receipt::try_from(elem).unwrap(); + Received::try_from(elem).unwrap(); } #[test] fn test_serialise() { - let receipt = Receipt::Request; + let receipt = Request; let elem: Element = receipt.into(); assert!(elem.is("request", ns::RECEIPTS)); + assert_eq!(elem.attrs().count(), 0); - let receipt = Receipt::Received(Some(String::from("coucou"))); + let receipt = Received { + id: Some(String::from("coucou")), + }; let elem: Element = receipt.into(); assert!(elem.is("received", ns::RECEIPTS)); assert_eq!(elem.attr("id"), Some("coucou"));