mirror of
https://gitlab.com/xmpp-rs/xmpp-rs.git
synced 2024-07-12 22:21:53 +00:00
idle: Add the chrono dependency to actually parse dates.
This commit is contained in:
parent
dfdfd8cf71
commit
2c77c4f701
4 changed files with 73 additions and 6 deletions
|
@ -18,3 +18,4 @@ sha-1 = "0.3.0"
|
|||
sha2 = "0.5.0"
|
||||
sha3 = "0.5.0"
|
||||
blake2 = "0.5.0"
|
||||
chrono = "0.3.1"
|
||||
|
|
|
@ -12,6 +12,7 @@ use std::string;
|
|||
use base64;
|
||||
use minidom;
|
||||
use jid;
|
||||
use chrono;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
|
@ -22,6 +23,7 @@ pub enum Error {
|
|||
ParseIntError(num::ParseIntError),
|
||||
ParseStringError(string::ParseError),
|
||||
JidParseError(jid::JidParseError),
|
||||
ChronoParseError(chrono::ParseError),
|
||||
}
|
||||
|
||||
impl From<io::Error> for Error {
|
||||
|
@ -59,3 +61,9 @@ impl From<jid::JidParseError> for Error {
|
|||
Error::JidParseError(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<chrono::ParseError> for Error {
|
||||
fn from(err: chrono::ParseError) -> Error {
|
||||
Error::ChronoParseError(err)
|
||||
}
|
||||
}
|
||||
|
|
69
src/idle.rs
69
src/idle.rs
|
@ -7,16 +7,15 @@
|
|||
use std::convert::TryFrom;
|
||||
|
||||
use minidom::Element;
|
||||
use chrono::prelude::*;
|
||||
|
||||
use error::Error;
|
||||
|
||||
use ns;
|
||||
|
||||
type Date = String;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Idle {
|
||||
pub since: Date,
|
||||
pub since: DateTime<FixedOffset>,
|
||||
}
|
||||
|
||||
impl TryFrom<Element> for Idle {
|
||||
|
@ -29,7 +28,7 @@ impl TryFrom<Element> for Idle {
|
|||
for _ in elem.children() {
|
||||
return Err(Error::ParseError("Unknown child in idle element."));
|
||||
}
|
||||
let since = get_attr!(elem, "since", required);
|
||||
let since = get_attr!(elem, "since", required, since, DateTime::parse_from_rfc3339(since)?);
|
||||
Ok(Idle { since: since })
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +37,7 @@ impl Into<Element> for Idle {
|
|||
fn into(self) -> Element {
|
||||
Element::builder("idle")
|
||||
.ns(ns::IDLE)
|
||||
.attr("since", self.since.clone())
|
||||
.attr("since", self.since.to_rfc3339())
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +45,7 @@ impl Into<Element> for Idle {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::error::Error as StdError;
|
||||
|
||||
#[test]
|
||||
fn test_simple() {
|
||||
|
@ -75,10 +75,67 @@ mod tests {
|
|||
assert_eq!(message, "Required attribute 'since' missing.");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_date() {
|
||||
// There is no thirteenth month.
|
||||
let elem: Element = "<idle xmlns='urn:xmpp:idle:1' since='2017-13-01T12:23:34Z'/>".parse().unwrap();
|
||||
let error = Idle::try_from(elem).unwrap_err();
|
||||
let message = match error {
|
||||
Error::ChronoParseError(string) => string,
|
||||
_ => panic!(),
|
||||
};
|
||||
assert_eq!(message.description(), "input is out of range");
|
||||
|
||||
// Timezone ≥24:00 aren’t allowed.
|
||||
let elem: Element = "<idle xmlns='urn:xmpp:idle:1' since='2017-05-27T12:11:02+25:00'/>".parse().unwrap();
|
||||
let error = Idle::try_from(elem).unwrap_err();
|
||||
let message = match error {
|
||||
Error::ChronoParseError(string) => string,
|
||||
_ => panic!(),
|
||||
};
|
||||
assert_eq!(message.description(), "input is out of range");
|
||||
|
||||
// Timezone without the : separator aren’t allowed.
|
||||
let elem: Element = "<idle xmlns='urn:xmpp:idle:1' since='2017-05-27T12:11:02+0100'/>".parse().unwrap();
|
||||
let error = Idle::try_from(elem).unwrap_err();
|
||||
let message = match error {
|
||||
Error::ChronoParseError(string) => string,
|
||||
_ => panic!(),
|
||||
};
|
||||
assert_eq!(message.description(), "input contains invalid characters");
|
||||
|
||||
// No seconds, error message could be improved.
|
||||
let elem: Element = "<idle xmlns='urn:xmpp:idle:1' since='2017-05-27T12:11+01:00'/>".parse().unwrap();
|
||||
let error = Idle::try_from(elem).unwrap_err();
|
||||
let message = match error {
|
||||
Error::ChronoParseError(string) => string,
|
||||
_ => panic!(),
|
||||
};
|
||||
assert_eq!(message.description(), "input contains invalid characters");
|
||||
|
||||
// TODO: maybe we’ll want to support this one, as per XEP-0082 §4.
|
||||
let elem: Element = "<idle xmlns='urn:xmpp:idle:1' since='20170527T12:11:02+01:00'/>".parse().unwrap();
|
||||
let error = Idle::try_from(elem).unwrap_err();
|
||||
let message = match error {
|
||||
Error::ChronoParseError(string) => string,
|
||||
_ => panic!(),
|
||||
};
|
||||
assert_eq!(message.description(), "input contains invalid characters");
|
||||
|
||||
// No timezone.
|
||||
let elem: Element = "<idle xmlns='urn:xmpp:idle:1' since='2017-05-27T12:11:02'/>".parse().unwrap();
|
||||
let error = Idle::try_from(elem).unwrap_err();
|
||||
let message = match error {
|
||||
Error::ChronoParseError(string) => string,
|
||||
_ => panic!(),
|
||||
};
|
||||
assert_eq!(message.description(), "premature end of input");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_serialise() {
|
||||
let elem: Element = "<idle xmlns='urn:xmpp:idle:1' since='2017-05-21T20:19:55+01:00'/>".parse().unwrap();
|
||||
let idle = Idle { since: Date::from("2017-05-21T20:19:55+01:00") };
|
||||
let idle = Idle { since: DateTime::parse_from_rfc3339("2017-05-21T20:19:55+01:00").unwrap() };
|
||||
let elem2 = idle.into();
|
||||
assert_eq!(elem, elem2);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ extern crate sha_1;
|
|||
extern crate sha2;
|
||||
extern crate sha3;
|
||||
extern crate blake2;
|
||||
extern crate chrono;
|
||||
|
||||
macro_rules! get_attr {
|
||||
($elem:ident, $attr:tt, $type:tt) => (
|
||||
|
|
Loading…
Reference in a new issue