Skip to content

Commit

Permalink
Use NaiveDate and NaiveTime instead of the Local version
Browse files Browse the repository at this point in the history
  • Loading branch information
luleyleo committed Apr 21, 2018
1 parent 6d12517 commit 7f014c1
Show file tree
Hide file tree
Showing 8 changed files with 178 additions and 43 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ keywords = ["untis", "webuntis"]
categories = ["api-bindings", "data-structures"]
license = "MIT"
readme = "README.md"
version = "0.1.0"
version = "0.2.0"
authors = ["Leopold Luley <[email protected]>"]

[dependencies]
Expand Down
15 changes: 8 additions & 7 deletions examples/fetch_all.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,17 @@ use untis::Units;

fn main() {
let mut untis = Units::new("server", "school", "user", "password");
let today = Local::today().naive_local();

let info = untis.login().expect("Failed to login");

let _statusdata = untis.status_data() .expect("Failed to get status data" );
let _holidays = untis.holidays() .expect("Failed to get holidays" );
let _rooms = untis.rooms() .expect("Failed to get rooms" );
let _classes = untis.classes() .expect("Failed to get classes" );
let _subjects = untis.subjects() .expect("Failed to get subjects" );
let _timetable = untis.timetable(info.class_id, 1, Local::today()) .expect("Failed to get timetable" );
let _departments = untis.departments() .expect("Failed to get departments" );
let _statusdata = untis.status_data() .expect("Failed to get status data" );
let _holidays = untis.holidays() .expect("Failed to get holidays" );
let _rooms = untis.rooms() .expect("Failed to get rooms" );
let _classes = untis.classes() .expect("Failed to get classes" );
let _subjects = untis.subjects() .expect("Failed to get subjects" );
let _timetable = untis.timetable(info.class_id, 1, today) .expect("Failed to get timetable" );
let _departments = untis.departments() .expect("Failed to get departments" );
// teachers

untis.logout().expect("Failed to logout");
Expand Down
48 changes: 22 additions & 26 deletions src/date.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,20 @@
use serde::{self, Deserialize, Deserializer, Serialize, Serializer};
use serde::de::Visitor;
use chrono::{Date, DateTime, Datelike, Local, TimeZone};
use chrono::{NaiveDate, Datelike, Duration, Local};
use std::ops::Deref;
use std::fmt;

#[derive(Debug)]
pub struct UntisDate(Date<Local>);

#[derive(Debug)]
pub struct UntisTime(DateTime<Local>);
pub struct UntisDate(NaiveDate);

impl UntisDate {
pub fn week_begin_from(date: Date<Local>) -> Self {
let day = date.day();
pub fn week_begin_from(date: NaiveDate) -> Self {
let days_from_monday = date.weekday().num_days_from_monday();
let monday = date.with_day(day - days_from_monday).unwrap();
let monday = date - Duration::days(days_from_monday as i64);
UntisDate(monday)
}

pub fn week_end_from(date: Date<Local>) -> Self {
pub fn week_end_from(date: NaiveDate) -> Self {
let day = date.day();
let days_from_monday = date.weekday().num_days_from_monday();
let days_left_till_friday = 5 - days_from_monday;
Expand All @@ -27,16 +23,16 @@ impl UntisDate {
}

pub fn week_begin() -> Self {
Self::week_begin_from(Local::today())
Self::week_begin_from(Local::today().naive_local())
}

pub fn week_end() -> Self {
Self::week_end_from(Local::today())
Self::week_end_from(Local::today().naive_local())
}
}

impl Deref for UntisDate {
type Target = Date<Local>;
type Target = NaiveDate;

fn deref(&self) -> &Self::Target {
&self.0
Expand All @@ -48,7 +44,7 @@ impl Serialize for UntisDate {
where
S: Serializer,
{
serializer.serialize_u32(local_to_untis_date_number(**self))
serializer.serialize_u32(chrono_to_untis_date(**self))
}
}

Expand All @@ -74,65 +70,65 @@ impl<'de> Visitor<'de> for UntisDateVisitor {
fn visit_i8<E>(self, value: i8) -> Result<Self::Value, E>
where E: serde::de::Error,
{
Ok(UntisDate(local_from_untis_date_number(value as u32)))
Ok(UntisDate(chrono_from_untis_date(value as u32)))
}

fn visit_i16<E>(self, value: i16) -> Result<Self::Value, E>
where E: serde::de::Error,
{
Ok(UntisDate(local_from_untis_date_number(value as u32)))
Ok(UntisDate(chrono_from_untis_date(value as u32)))
}

fn visit_i32<E>(self, value: i32) -> Result<Self::Value, E>
where E: serde::de::Error,
{
Ok(UntisDate(local_from_untis_date_number(value as u32)))
Ok(UntisDate(chrono_from_untis_date(value as u32)))
}

fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
where E: serde::de::Error,
{
Ok(UntisDate(local_from_untis_date_number(value as u32)))
Ok(UntisDate(chrono_from_untis_date(value as u32)))
}

fn visit_u8<E>(self, value: u8) -> Result<Self::Value, E>
where E: serde::de::Error,
{
Ok(UntisDate(local_from_untis_date_number(value as u32)))
Ok(UntisDate(chrono_from_untis_date(value as u32)))
}

fn visit_u16<E>(self, value: u16) -> Result<Self::Value, E>
where E: serde::de::Error,
{
Ok(UntisDate(local_from_untis_date_number(value as u32)))
Ok(UntisDate(chrono_from_untis_date(value as u32)))
}

fn visit_u32<E>(self, value: u32) -> Result<Self::Value, E>
where E: serde::de::Error,
{
Ok(UntisDate(local_from_untis_date_number(value as u32)))
Ok(UntisDate(chrono_from_untis_date(value as u32)))
}

fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
where E: serde::de::Error,
{
Ok(UntisDate(local_from_untis_date_number(value as u32)))
Ok(UntisDate(chrono_from_untis_date(value as u32)))
}
}

fn local_to_untis_date_number(date: Date<Local>) -> u32 {
fn chrono_to_untis_date(date: NaiveDate) -> u32 {
let string = format!("{}", date.format("%Y%m%d"));
let number = string.parse::<u32>().unwrap();
number
}

fn local_from_untis_date_number(value: u32) -> Date<Local> {
fn chrono_from_untis_date(value: u32) -> NaiveDate {
let string = format!("{}", value);
let year = string[0..4].parse::<i32>().unwrap();
let month = string[4..6].parse::<u32>().unwrap();
let day = string[6..8].parse::<u32>().unwrap();

Local.ymd(year, month, day)
NaiveDate::from_ymd(year, month, day)
}

#[cfg(test)]
Expand All @@ -143,8 +139,8 @@ mod tests {
#[test]
fn convert_untis_date_forth_and_back() {
let number = 20180316;
let date = local_from_untis_date_number(number);
let new_number = local_to_untis_date_number(date);
let date = chrono_from_untis_date(number);
let new_number = chrono_to_untis_date(date);

assert_eq!(number, new_number);
}
Expand Down
8 changes: 7 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
//! Library to access [Untis](https://www.untis.at)
//!
//! The core of this crate is the `Untis` struct.
extern crate chrono;
extern crate reqwest;
extern crate serde;
Expand All @@ -11,9 +15,11 @@ mod request;
mod response;
mod untis;
mod date;
mod time;

pub use error::Error;
pub use request::*;
pub use response::*;
pub use untis::Units;
pub use date::*;
pub use date::UntisDate;
pub use time::UntisTime;
4 changes: 2 additions & 2 deletions src/request.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use serde::Serialize;

use chrono::{Date, Local};
use chrono::NaiveDate;

use date::UntisDate;

Expand Down Expand Up @@ -53,7 +53,7 @@ pub struct ParamsTimetable {
}

impl ParamsTimetable {
pub fn new(id: usize, ty: usize, date: Date<Local>) -> Self {
pub fn new(id: usize, ty: usize, date: NaiveDate) -> Self {
ParamsTimetable {
id,
ty,
Expand Down
9 changes: 5 additions & 4 deletions src/response.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::collections::HashMap;
use date::UntisDate;
use time::UntisTime;

#[derive(Debug, Deserialize)]
pub struct RpcResponse<R> {
Expand Down Expand Up @@ -41,8 +42,8 @@ pub struct HolidaysItem {
pub id: usize,
pub name: String,
pub long_name: String,
pub start_date: usize,
pub end_date: usize,
pub start_date: UntisDate,
pub end_date: UntisDate,
}

pub type Rooms = Vec<RoomItem>;
Expand Down Expand Up @@ -101,8 +102,8 @@ pub type Timetable = Vec<TimetableItem>;
pub struct TimetableItem {
pub id: usize,
pub date: UntisDate,
pub start_time: usize,
pub end_time: usize,
pub start_time: UntisTime,
pub end_time: UntisTime,

#[serde(rename = "kl")]
pub classes: Vec<IdItem>,
Expand Down
124 changes: 124 additions & 0 deletions src/time.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
use serde::{self, Deserialize, Deserializer, Serialize, Serializer};
use serde::de::Visitor;
use chrono::NaiveTime;
use std::ops::Deref;
use std::fmt;

#[derive(Debug)]
pub struct UntisTime(NaiveTime);

impl Deref for UntisTime {
type Target = NaiveTime;

fn deref(&self) -> &Self::Target {
&self.0
}
}

impl Serialize for UntisTime {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_u32(chrono_to_untis_time(**self))
}
}

impl<'de> Deserialize<'de> for UntisTime {
fn deserialize<D>(deserializer: D) -> Result<UntisTime, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_u32(UntisTimeVisitor)
}
}

struct UntisTimeVisitor;

impl<'de> Visitor<'de> for UntisTimeVisitor {
type Value = UntisTime;

fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter
.write_str("an integer in the format YEARMONTHDAY like 20180316 for the 16. March 2018")
}

fn visit_i8<E>(self, value: i8) -> Result<Self::Value, E>
where E: serde::de::Error,
{
Ok(UntisTime(chrono_from_untis_time(value as u32)))
}

fn visit_i16<E>(self, value: i16) -> Result<Self::Value, E>
where E: serde::de::Error,
{
Ok(UntisTime(chrono_from_untis_time(value as u32)))
}

fn visit_i32<E>(self, value: i32) -> Result<Self::Value, E>
where E: serde::de::Error,
{
Ok(UntisTime(chrono_from_untis_time(value as u32)))
}

fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
where E: serde::de::Error,
{
Ok(UntisTime(chrono_from_untis_time(value as u32)))
}

fn visit_u8<E>(self, value: u8) -> Result<Self::Value, E>
where E: serde::de::Error,
{
Ok(UntisTime(chrono_from_untis_time(value as u32)))
}

fn visit_u16<E>(self, value: u16) -> Result<Self::Value, E>
where E: serde::de::Error,
{
Ok(UntisTime(chrono_from_untis_time(value as u32)))
}

fn visit_u32<E>(self, value: u32) -> Result<Self::Value, E>
where E: serde::de::Error,
{
Ok(UntisTime(chrono_from_untis_time(value as u32)))
}

fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
where E: serde::de::Error,
{
Ok(UntisTime(chrono_from_untis_time(value as u32)))
}
}

fn chrono_to_untis_time(time: NaiveTime) -> u32 {
let string = format!("{}", time.format("%k%M"));
let number = string.trim().parse::<u32>().unwrap();
number
}

fn chrono_from_untis_time(value: u32) -> NaiveTime {
let string = format!("{}", value);
let hour_len = if string.len() == 3 { 1 } else { 2 };
let hours = string[0..hour_len].parse::<u32>().unwrap();
let mins = string[hour_len..(hour_len+2)].parse::<u32>().unwrap();

NaiveTime::from_hms(hours, mins, 0)
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn convert_untis_time_forth_and_back() {
let number = 830;
let time = chrono_from_untis_time(number);
println!("Time: {}", time);
let new_number = chrono_to_untis_time(time);
println!("Num: {}", new_number);

assert_eq!(number, new_number);
}
}
Loading

0 comments on commit 7f014c1

Please sign in to comment.