forked from mirrors/gstreamer-rs
gstreamer/datetime: Check invariants on the bindings side instead of asserting in the C code
Newer versions of GStreamer (1.20 and above) will not assert any longer but handle it more gracefully, so let's do the same here for all versions. Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/issues/297
This commit is contained in:
parent
584a87163f
commit
15722ec5d2
4 changed files with 437 additions and 156 deletions
|
@ -1654,9 +1654,63 @@ status = "generate"
|
||||||
|
|
||||||
[[object.function]]
|
[[object.function]]
|
||||||
name = "new"
|
name = "new"
|
||||||
[object.function.return]
|
# Needs manual checking of invariants
|
||||||
nullable = true
|
manual = true
|
||||||
nullable_return_is_error = "Can't create DateTime"
|
|
||||||
|
[[object.function]]
|
||||||
|
name = "new_local_time"
|
||||||
|
# Needs manual checking of invariants
|
||||||
|
manual = true
|
||||||
|
|
||||||
|
[[object.function]]
|
||||||
|
name = "new_y"
|
||||||
|
# Needs manual checking of invariants
|
||||||
|
manual = true
|
||||||
|
|
||||||
|
[[object.function]]
|
||||||
|
name = "new_ym"
|
||||||
|
# Needs manual checking of invariants
|
||||||
|
manual = true
|
||||||
|
|
||||||
|
[[object.function]]
|
||||||
|
name = "new_ymd"
|
||||||
|
# Needs manual checking of invariants
|
||||||
|
manual = true
|
||||||
|
|
||||||
|
[[object.function]]
|
||||||
|
name = "get_month"
|
||||||
|
# Needs manual checking of invariants
|
||||||
|
manual = true
|
||||||
|
|
||||||
|
[[object.function]]
|
||||||
|
name = "get_day"
|
||||||
|
# Needs manual checking of invariants
|
||||||
|
manual = true
|
||||||
|
|
||||||
|
[[object.function]]
|
||||||
|
name = "get_hour"
|
||||||
|
# Needs manual checking of invariants
|
||||||
|
manual = true
|
||||||
|
|
||||||
|
[[object.function]]
|
||||||
|
name = "get_minute"
|
||||||
|
# Needs manual checking of invariants
|
||||||
|
manual = true
|
||||||
|
|
||||||
|
[[object.function]]
|
||||||
|
name = "get_second"
|
||||||
|
# Needs manual checking of invariants
|
||||||
|
manual = true
|
||||||
|
|
||||||
|
[[object.function]]
|
||||||
|
name = "get_microsecond"
|
||||||
|
# Needs manual checking of invariants
|
||||||
|
manual = true
|
||||||
|
|
||||||
|
[[object.function]]
|
||||||
|
name = "get_time_zone_offset"
|
||||||
|
# Needs manual checking of invariants
|
||||||
|
manual = true
|
||||||
|
|
||||||
[[object.function]]
|
[[object.function]]
|
||||||
name = "new_y"
|
name = "new_y"
|
||||||
|
@ -1696,6 +1750,26 @@ status = "generate"
|
||||||
[object.function.return]
|
[object.function.return]
|
||||||
nullable_return_is_error = "Failed to create ISO-8601 string from DateTime"
|
nullable_return_is_error = "Failed to create ISO-8601 string from DateTime"
|
||||||
|
|
||||||
|
[[object.function]]
|
||||||
|
name = "new_from_unix_epoch_local_time"
|
||||||
|
[object.function.return]
|
||||||
|
nullable_return_is_error = "Can't create DateTime from UNIX epoch"
|
||||||
|
|
||||||
|
[[object.function]]
|
||||||
|
name = "new_from_unix_epoch_local_time_usecs"
|
||||||
|
[object.function.return]
|
||||||
|
nullable_return_is_error = "Can't create DateTime from UNIX epoch"
|
||||||
|
|
||||||
|
[[object.function]]
|
||||||
|
name = "new_from_unix_epoch_utc"
|
||||||
|
[object.function.return]
|
||||||
|
nullable_return_is_error = "Can't create DateTime from UNIX epoch"
|
||||||
|
|
||||||
|
[[object.function]]
|
||||||
|
name = "new_from_unix_epoch_utc_usecs"
|
||||||
|
[object.function.return]
|
||||||
|
nullable_return_is_error = "Can't create DateTime from UNIX epoch"
|
||||||
|
|
||||||
[[object]]
|
[[object]]
|
||||||
name = "Gst.ControlSource"
|
name = "Gst.ControlSource"
|
||||||
status = "generate"
|
status = "generate"
|
||||||
|
|
|
@ -16,24 +16,6 @@ glib::glib_wrapper! {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DateTime {
|
impl DateTime {
|
||||||
pub fn new(
|
|
||||||
tzoffset: f32,
|
|
||||||
year: i32,
|
|
||||||
month: i32,
|
|
||||||
day: i32,
|
|
||||||
hour: i32,
|
|
||||||
minute: i32,
|
|
||||||
seconds: f64,
|
|
||||||
) -> Result<DateTime, glib::BoolError> {
|
|
||||||
assert_initialized_main_thread!();
|
|
||||||
unsafe {
|
|
||||||
Option::<_>::from_glib_full(ffi::gst_date_time_new(
|
|
||||||
tzoffset, year, month, day, hour, minute, seconds,
|
|
||||||
))
|
|
||||||
.ok_or_else(|| glib::glib_bool_error!("Can't create DateTime"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from_g_date_time(dt: &glib::DateTime) -> Result<DateTime, glib::BoolError> {
|
pub fn from_g_date_time(dt: &glib::DateTime) -> Result<DateTime, glib::BoolError> {
|
||||||
assert_initialized_main_thread!();
|
assert_initialized_main_thread!();
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -52,47 +34,41 @@ impl DateTime {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_unix_epoch_local_time(secs: i64) -> Option<DateTime> {
|
pub fn from_unix_epoch_local_time(secs: i64) -> Result<DateTime, glib::BoolError> {
|
||||||
assert_initialized_main_thread!();
|
|
||||||
unsafe { from_glib_full(ffi::gst_date_time_new_from_unix_epoch_local_time(secs)) }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(any(feature = "v1_18", feature = "dox"))]
|
|
||||||
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))]
|
|
||||||
pub fn from_unix_epoch_local_time_usecs(usecs: i64) -> Option<DateTime> {
|
|
||||||
assert_initialized_main_thread!();
|
assert_initialized_main_thread!();
|
||||||
unsafe {
|
unsafe {
|
||||||
from_glib_full(ffi::gst_date_time_new_from_unix_epoch_local_time_usecs(
|
Option::<_>::from_glib_full(ffi::gst_date_time_new_from_unix_epoch_local_time(secs))
|
||||||
usecs,
|
.ok_or_else(|| glib::glib_bool_error!("Can't create DateTime from UNIX epoch"))
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_unix_epoch_utc(secs: i64) -> Option<DateTime> {
|
#[cfg(any(feature = "v1_18", feature = "dox"))]
|
||||||
|
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))]
|
||||||
|
pub fn from_unix_epoch_local_time_usecs(usecs: i64) -> Result<DateTime, glib::BoolError> {
|
||||||
assert_initialized_main_thread!();
|
assert_initialized_main_thread!();
|
||||||
unsafe { from_glib_full(ffi::gst_date_time_new_from_unix_epoch_utc(secs)) }
|
unsafe {
|
||||||
|
Option::<_>::from_glib_full(ffi::gst_date_time_new_from_unix_epoch_local_time_usecs(
|
||||||
|
usecs,
|
||||||
|
))
|
||||||
|
.ok_or_else(|| glib::glib_bool_error!("Can't create DateTime from UNIX epoch"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_unix_epoch_utc(secs: i64) -> Result<DateTime, glib::BoolError> {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
unsafe {
|
||||||
|
Option::<_>::from_glib_full(ffi::gst_date_time_new_from_unix_epoch_utc(secs))
|
||||||
|
.ok_or_else(|| glib::glib_bool_error!("Can't create DateTime from UNIX epoch"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "v1_18", feature = "dox"))]
|
#[cfg(any(feature = "v1_18", feature = "dox"))]
|
||||||
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))]
|
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))]
|
||||||
pub fn from_unix_epoch_utc_usecs(usecs: i64) -> Option<DateTime> {
|
pub fn from_unix_epoch_utc_usecs(usecs: i64) -> Result<DateTime, glib::BoolError> {
|
||||||
assert_initialized_main_thread!();
|
|
||||||
unsafe { from_glib_full(ffi::gst_date_time_new_from_unix_epoch_utc_usecs(usecs)) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_local_time(
|
|
||||||
year: i32,
|
|
||||||
month: i32,
|
|
||||||
day: i32,
|
|
||||||
hour: i32,
|
|
||||||
minute: i32,
|
|
||||||
seconds: f64,
|
|
||||||
) -> Option<DateTime> {
|
|
||||||
assert_initialized_main_thread!();
|
assert_initialized_main_thread!();
|
||||||
unsafe {
|
unsafe {
|
||||||
from_glib_full(ffi::gst_date_time_new_local_time(
|
Option::<_>::from_glib_full(ffi::gst_date_time_new_from_unix_epoch_utc_usecs(usecs))
|
||||||
year, month, day, hour, minute, seconds,
|
.ok_or_else(|| glib::glib_bool_error!("Can't create DateTime from UNIX epoch"))
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,58 +82,6 @@ impl DateTime {
|
||||||
unsafe { from_glib_full(ffi::gst_date_time_new_now_utc()) }
|
unsafe { from_glib_full(ffi::gst_date_time_new_now_utc()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_y(year: i32) -> Result<DateTime, glib::BoolError> {
|
|
||||||
assert_initialized_main_thread!();
|
|
||||||
unsafe {
|
|
||||||
Option::<_>::from_glib_full(ffi::gst_date_time_new_y(year))
|
|
||||||
.ok_or_else(|| glib::glib_bool_error!("Can't create DateTime"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_ym(year: i32, month: i32) -> Result<DateTime, glib::BoolError> {
|
|
||||||
assert_initialized_main_thread!();
|
|
||||||
unsafe {
|
|
||||||
Option::<_>::from_glib_full(ffi::gst_date_time_new_ym(year, month))
|
|
||||||
.ok_or_else(|| glib::glib_bool_error!("Can't create DateTime"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_ymd(year: i32, month: i32, day: i32) -> Result<DateTime, glib::BoolError> {
|
|
||||||
assert_initialized_main_thread!();
|
|
||||||
unsafe {
|
|
||||||
Option::<_>::from_glib_full(ffi::gst_date_time_new_ymd(year, month, day))
|
|
||||||
.ok_or_else(|| glib::glib_bool_error!("Can't create DateTime"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_day(&self) -> i32 {
|
|
||||||
unsafe { ffi::gst_date_time_get_day(self.to_glib_none().0) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_hour(&self) -> i32 {
|
|
||||||
unsafe { ffi::gst_date_time_get_hour(self.to_glib_none().0) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_microsecond(&self) -> i32 {
|
|
||||||
unsafe { ffi::gst_date_time_get_microsecond(self.to_glib_none().0) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_minute(&self) -> i32 {
|
|
||||||
unsafe { ffi::gst_date_time_get_minute(self.to_glib_none().0) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_month(&self) -> i32 {
|
|
||||||
unsafe { ffi::gst_date_time_get_month(self.to_glib_none().0) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_second(&self) -> i32 {
|
|
||||||
unsafe { ffi::gst_date_time_get_second(self.to_glib_none().0) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_time_zone_offset(&self) -> f32 {
|
|
||||||
unsafe { ffi::gst_date_time_get_time_zone_offset(self.to_glib_none().0) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_year(&self) -> i32 {
|
pub fn get_year(&self) -> i32 {
|
||||||
unsafe { ffi::gst_date_time_get_year(self.to_glib_none().0) }
|
unsafe { ffi::gst_date_time_get_year(self.to_glib_none().0) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,13 +6,291 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
|
use glib::translate::*;
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::convert;
|
use std::convert;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use crate::DateTime;
|
use crate::DateTime;
|
||||||
|
|
||||||
|
// Validate that the given values result in a valid DateTime
|
||||||
|
fn validate(
|
||||||
|
tzoffset: Option<f32>,
|
||||||
|
year: i32,
|
||||||
|
month: Option<i32>,
|
||||||
|
day: Option<i32>,
|
||||||
|
hour: Option<i32>,
|
||||||
|
minute: Option<i32>,
|
||||||
|
seconds: Option<f64>,
|
||||||
|
) -> Result<(), glib::BoolError> {
|
||||||
|
skip_assert_initialized!();
|
||||||
|
|
||||||
|
// Check for valid ranges
|
||||||
|
if year <= 0 || year > 9999 {
|
||||||
|
return Err(glib::glib_bool_error!(
|
||||||
|
"Can't create DateTime: Year out of range"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(month) = month {
|
||||||
|
if month <= 0 || month > 12 {
|
||||||
|
return Err(glib::glib_bool_error!(
|
||||||
|
"Can't create DateTime: Month out of range"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(day) = day {
|
||||||
|
if day <= 0 || day > 31 {
|
||||||
|
return Err(glib::glib_bool_error!(
|
||||||
|
"Can't create DateTime: Day out of range"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(hour) = hour {
|
||||||
|
if hour < 0 || hour >= 24 {
|
||||||
|
return Err(glib::glib_bool_error!(
|
||||||
|
"Can't create DateTime: Hour out of range"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(minute) = minute {
|
||||||
|
if minute < 0 || minute >= 60 {
|
||||||
|
return Err(glib::glib_bool_error!(
|
||||||
|
"Can't create DateTime: Minute out of range"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(seconds) = seconds {
|
||||||
|
if seconds < 0.0 || seconds >= 60.0 {
|
||||||
|
return Err(glib::glib_bool_error!(
|
||||||
|
"Can't create DateTime: Seconds out of range"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(tzoffset) = tzoffset {
|
||||||
|
if tzoffset < -12.0 || tzoffset > 12.0 {
|
||||||
|
return Err(glib::glib_bool_error!(
|
||||||
|
"Can't create DateTime: Timezone offset out of range"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If day is provided, month also has to be provided
|
||||||
|
if day.is_some() && month.is_none() {
|
||||||
|
return Err(glib::glib_bool_error!(
|
||||||
|
"Can't create DateTime: Need to provide month if providing day"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// If hour is provided, day also has to be provided
|
||||||
|
if hour.is_some() && day.is_none() {
|
||||||
|
return Err(glib::glib_bool_error!(
|
||||||
|
"Can't create DateTime: Need to provide day if providing hour"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// If minutes are provided, hours also need to be provided and the other way around
|
||||||
|
if hour.is_none() && minute.is_some() {
|
||||||
|
return Err(glib::glib_bool_error!(
|
||||||
|
"Can't create DateTime: Need to provide both hour and minute or neither"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if minute.is_some() && hour.is_none() {
|
||||||
|
return Err(glib::glib_bool_error!(
|
||||||
|
"Can't create DateTime: Need to provide both hour and minute or neither"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// If seconds or tzoffset are provided then also hours and minutes must be provided
|
||||||
|
if (seconds.is_some() || tzoffset.is_some()) && (hour.is_none() || minute.is_none()) {
|
||||||
|
return Err(glib::glib_bool_error!("Can't create DateTime: Need to provide hour and minute if providing seconds or timezone offset"));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
impl DateTime {
|
impl DateTime {
|
||||||
|
pub fn new<
|
||||||
|
TZ: Into<Option<f32>>,
|
||||||
|
Y: Into<i32>,
|
||||||
|
MO: Into<Option<i32>>,
|
||||||
|
D: Into<Option<i32>>,
|
||||||
|
H: Into<Option<i32>>,
|
||||||
|
MI: Into<Option<i32>>,
|
||||||
|
S: Into<Option<f64>>,
|
||||||
|
>(
|
||||||
|
tzoffset: TZ,
|
||||||
|
year: Y,
|
||||||
|
month: MO,
|
||||||
|
day: D,
|
||||||
|
hour: H,
|
||||||
|
minute: MI,
|
||||||
|
seconds: S,
|
||||||
|
) -> Result<DateTime, glib::BoolError> {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
|
||||||
|
let tzoffset = tzoffset.into();
|
||||||
|
let year = year.into();
|
||||||
|
let month = month.into();
|
||||||
|
let day = day.into();
|
||||||
|
let hour = hour.into();
|
||||||
|
let minute = minute.into();
|
||||||
|
let seconds = seconds.into();
|
||||||
|
|
||||||
|
validate(tzoffset, year, month, day, hour, minute, seconds)?;
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
Option::<_>::from_glib_full(ffi::gst_date_time_new(
|
||||||
|
tzoffset.unwrap_or(0.0),
|
||||||
|
year,
|
||||||
|
month.unwrap_or(-1),
|
||||||
|
day.unwrap_or(-1),
|
||||||
|
hour.unwrap_or(-1),
|
||||||
|
minute.unwrap_or(-1),
|
||||||
|
seconds.unwrap_or(-1.0),
|
||||||
|
))
|
||||||
|
.ok_or_else(|| glib::glib_bool_error!("Can't create DateTime"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_local_time<
|
||||||
|
Y: Into<i32>,
|
||||||
|
MO: Into<Option<i32>>,
|
||||||
|
D: Into<Option<i32>>,
|
||||||
|
H: Into<Option<i32>>,
|
||||||
|
MI: Into<Option<i32>>,
|
||||||
|
S: Into<Option<f64>>,
|
||||||
|
>(
|
||||||
|
year: Y,
|
||||||
|
month: MO,
|
||||||
|
day: D,
|
||||||
|
hour: H,
|
||||||
|
minute: MI,
|
||||||
|
seconds: S,
|
||||||
|
) -> Result<DateTime, glib::BoolError> {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
|
||||||
|
let year = year.into();
|
||||||
|
let month = month.into();
|
||||||
|
let day = day.into();
|
||||||
|
let hour = hour.into();
|
||||||
|
let minute = minute.into();
|
||||||
|
let seconds = seconds.into();
|
||||||
|
|
||||||
|
validate(None, year, month, day, hour, minute, seconds)?;
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
Option::<_>::from_glib_full(ffi::gst_date_time_new_local_time(
|
||||||
|
year,
|
||||||
|
month.unwrap_or(-1),
|
||||||
|
day.unwrap_or(-1),
|
||||||
|
hour.unwrap_or(-1),
|
||||||
|
minute.unwrap_or(-1),
|
||||||
|
seconds.unwrap_or(-1.0),
|
||||||
|
))
|
||||||
|
.ok_or_else(|| glib::glib_bool_error!("Can't create DateTime"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_y(year: i32) -> Result<DateTime, glib::BoolError> {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
|
||||||
|
validate(None, year, None, None, None, None, None)?;
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
Option::<_>::from_glib_full(ffi::gst_date_time_new_y(year))
|
||||||
|
.ok_or_else(|| glib::glib_bool_error!("Can't create DateTime"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_ym(year: i32, month: i32) -> Result<DateTime, glib::BoolError> {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
|
||||||
|
validate(None, year, Some(month), None, None, None, None)?;
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
Option::<_>::from_glib_full(ffi::gst_date_time_new_ym(year, month))
|
||||||
|
.ok_or_else(|| glib::glib_bool_error!("Can't create DateTime"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_ymd(year: i32, month: i32, day: i32) -> Result<DateTime, glib::BoolError> {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
|
||||||
|
validate(None, year, Some(month), Some(day), None, None, None)?;
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
Option::<_>::from_glib_full(ffi::gst_date_time_new_ymd(year, month, day))
|
||||||
|
.ok_or_else(|| glib::glib_bool_error!("Can't create DateTime"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_day(&self) -> Option<i32> {
|
||||||
|
if !self.has_day() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe { Some(ffi::gst_date_time_get_day(self.to_glib_none().0)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_hour(&self) -> Option<i32> {
|
||||||
|
if !self.has_time() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe { Some(ffi::gst_date_time_get_hour(self.to_glib_none().0)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_microsecond(&self) -> Option<i32> {
|
||||||
|
if !self.has_second() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe { Some(ffi::gst_date_time_get_microsecond(self.to_glib_none().0)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_minute(&self) -> Option<i32> {
|
||||||
|
if !self.has_time() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe { Some(ffi::gst_date_time_get_minute(self.to_glib_none().0)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_month(&self) -> Option<i32> {
|
||||||
|
if !self.has_month() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe { Some(ffi::gst_date_time_get_month(self.to_glib_none().0)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_second(&self) -> Option<i32> {
|
||||||
|
if !self.has_second() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe { Some(ffi::gst_date_time_get_second(self.to_glib_none().0)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_time_zone_offset(&self) -> Option<f32> {
|
||||||
|
if !self.has_time() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
Some(ffi::gst_date_time_get_time_zone_offset(
|
||||||
|
self.to_glib_none().0,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn to_utc(&self) -> Result<DateTime, glib::BoolError> {
|
pub fn to_utc(&self) -> Result<DateTime, glib::BoolError> {
|
||||||
if !self.has_time() {
|
if !self.has_time() {
|
||||||
// No time => no TZ offset
|
// No time => no TZ offset
|
||||||
|
@ -43,7 +321,7 @@ impl DateTime {
|
||||||
self.get_day(),
|
self.get_day(),
|
||||||
self.get_hour(),
|
self.get_hour(),
|
||||||
self.get_minute(),
|
self.get_minute(),
|
||||||
0f64,
|
Some(0.0),
|
||||||
)
|
)
|
||||||
.and_then(|d| d.to_g_date_time())
|
.and_then(|d| d.to_g_date_time())
|
||||||
.and_then(|d| {
|
.and_then(|d| {
|
||||||
|
@ -52,13 +330,13 @@ impl DateTime {
|
||||||
})
|
})
|
||||||
.and_then(|d| {
|
.and_then(|d| {
|
||||||
DateTime::new(
|
DateTime::new(
|
||||||
0f32, // UTC TZ offset
|
None, // UTC TZ offset
|
||||||
d.get_year(),
|
d.get_year(),
|
||||||
d.get_month(),
|
Some(d.get_month()),
|
||||||
d.get_day_of_month(),
|
Some(d.get_day_of_month()),
|
||||||
d.get_hour(),
|
Some(d.get_hour()),
|
||||||
d.get_minute(),
|
Some(d.get_minute()),
|
||||||
-1f64, // No second
|
None, // No second
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -121,7 +399,7 @@ impl cmp::PartialOrd for DateTime {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let month_delta = self_norm.get_month() - other_norm.get_month();
|
let month_delta = self_norm.get_month().unwrap() - other_norm.get_month().unwrap();
|
||||||
if month_delta != 0 {
|
if month_delta != 0 {
|
||||||
return get_cmp(month_delta);
|
return get_cmp(month_delta);
|
||||||
}
|
}
|
||||||
|
@ -138,7 +416,7 @@ impl cmp::PartialOrd for DateTime {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let day_delta = self_norm.get_day() - other_norm.get_day();
|
let day_delta = self_norm.get_day().unwrap() - other_norm.get_day().unwrap();
|
||||||
if day_delta != 0 {
|
if day_delta != 0 {
|
||||||
return get_cmp(day_delta);
|
return get_cmp(day_delta);
|
||||||
}
|
}
|
||||||
|
@ -155,12 +433,12 @@ impl cmp::PartialOrd for DateTime {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let hour_delta = self_norm.get_hour() - other_norm.get_hour();
|
let hour_delta = self_norm.get_hour().unwrap() - other_norm.get_hour().unwrap();
|
||||||
if hour_delta != 0 {
|
if hour_delta != 0 {
|
||||||
return get_cmp(hour_delta);
|
return get_cmp(hour_delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
let minute_delta = self_norm.get_minute() - other_norm.get_minute();
|
let minute_delta = self_norm.get_minute().unwrap() - other_norm.get_minute().unwrap();
|
||||||
if minute_delta != 0 {
|
if minute_delta != 0 {
|
||||||
return get_cmp(minute_delta);
|
return get_cmp(minute_delta);
|
||||||
}
|
}
|
||||||
|
@ -176,12 +454,12 @@ impl cmp::PartialOrd for DateTime {
|
||||||
// One has second, the other doesn't => can't compare (note 1)
|
// One has second, the other doesn't => can't compare (note 1)
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let second_delta = self_norm.get_second() - other_norm.get_second();
|
let second_delta = self_norm.get_second().unwrap() - other_norm.get_second().unwrap();
|
||||||
if second_delta != 0 {
|
if second_delta != 0 {
|
||||||
return get_cmp(second_delta);
|
return get_cmp(second_delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
get_cmp(self_norm.get_microsecond() - other_norm.get_microsecond())
|
get_cmp(self_norm.get_microsecond().unwrap() - other_norm.get_microsecond().unwrap())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,12 +559,12 @@ mod tests {
|
||||||
.to_utc()
|
.to_utc()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(utc_date_time.get_year(), 2019);
|
assert_eq!(utc_date_time.get_year(), 2019);
|
||||||
assert_eq!(utc_date_time.get_month(), 8);
|
assert_eq!(utc_date_time.get_month().unwrap(), 8);
|
||||||
assert_eq!(utc_date_time.get_day(), 20);
|
assert_eq!(utc_date_time.get_day().unwrap(), 20);
|
||||||
assert_eq!(utc_date_time.get_hour(), 18);
|
assert_eq!(utc_date_time.get_hour().unwrap(), 18);
|
||||||
assert_eq!(utc_date_time.get_minute(), 9);
|
assert_eq!(utc_date_time.get_minute().unwrap(), 9);
|
||||||
assert_eq!(utc_date_time.get_second(), 42);
|
assert_eq!(utc_date_time.get_second().unwrap(), 42);
|
||||||
assert_eq!(utc_date_time.get_microsecond(), 123_456);
|
assert_eq!(utc_date_time.get_microsecond().unwrap(), 123_456);
|
||||||
|
|
||||||
// Year, month, day and hour offset
|
// Year, month, day and hour offset
|
||||||
let utc_date_time = DateTime::new(2f32, 2019, 1, 1, 0, 0, 42.123_456f64)
|
let utc_date_time = DateTime::new(2f32, 2019, 1, 1, 0, 0, 42.123_456f64)
|
||||||
|
@ -294,31 +572,31 @@ mod tests {
|
||||||
.to_utc()
|
.to_utc()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(utc_date_time.get_year(), 2018);
|
assert_eq!(utc_date_time.get_year(), 2018);
|
||||||
assert_eq!(utc_date_time.get_month(), 12);
|
assert_eq!(utc_date_time.get_month().unwrap(), 12);
|
||||||
assert_eq!(utc_date_time.get_day(), 31);
|
assert_eq!(utc_date_time.get_day().unwrap(), 31);
|
||||||
assert_eq!(utc_date_time.get_hour(), 22);
|
assert_eq!(utc_date_time.get_hour().unwrap(), 22);
|
||||||
assert_eq!(utc_date_time.get_minute(), 0);
|
assert_eq!(utc_date_time.get_minute().unwrap(), 0);
|
||||||
assert_eq!(utc_date_time.get_second(), 42);
|
assert_eq!(utc_date_time.get_second().unwrap(), 42);
|
||||||
assert_eq!(utc_date_time.get_microsecond(), 123_456);
|
assert_eq!(utc_date_time.get_microsecond().unwrap(), 123_456);
|
||||||
|
|
||||||
// Date without an hour (which implies no TZ)
|
// Date without an hour (which implies no TZ)
|
||||||
let utc_date_time = DateTime::new_ymd(2019, 1, 1).unwrap().to_utc().unwrap();
|
let utc_date_time = DateTime::new_ymd(2019, 1, 1).unwrap().to_utc().unwrap();
|
||||||
assert_eq!(utc_date_time.get_year(), 2019);
|
assert_eq!(utc_date_time.get_year(), 2019);
|
||||||
assert_eq!(utc_date_time.get_month(), 1);
|
assert_eq!(utc_date_time.get_month().unwrap(), 1);
|
||||||
assert_eq!(utc_date_time.get_day(), 1);
|
assert_eq!(utc_date_time.get_day().unwrap(), 1);
|
||||||
assert!(!utc_date_time.has_time());
|
assert!(!utc_date_time.has_time());
|
||||||
assert!(!utc_date_time.has_second());
|
assert!(!utc_date_time.has_second());
|
||||||
|
|
||||||
// Date without seconds
|
// Date without seconds
|
||||||
let utc_date_time = DateTime::new(2f32, 2018, 5, 28, 16, 6, -1f64)
|
let utc_date_time = DateTime::new(2f32, 2018, 5, 28, 16, 6, None)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_utc()
|
.to_utc()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(utc_date_time.get_year(), 2018);
|
assert_eq!(utc_date_time.get_year(), 2018);
|
||||||
assert_eq!(utc_date_time.get_month(), 5);
|
assert_eq!(utc_date_time.get_month().unwrap(), 5);
|
||||||
assert_eq!(utc_date_time.get_day(), 28);
|
assert_eq!(utc_date_time.get_day().unwrap(), 28);
|
||||||
assert_eq!(utc_date_time.get_hour(), 14);
|
assert_eq!(utc_date_time.get_hour().unwrap(), 14);
|
||||||
assert_eq!(utc_date_time.get_minute(), 6);
|
assert_eq!(utc_date_time.get_minute().unwrap(), 6);
|
||||||
assert!(!utc_date_time.has_second());
|
assert!(!utc_date_time.has_second());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,8 +720,8 @@ mod tests {
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
DateTime::new(2f32, 2018, 5, 28, 16, 6, -1f64).unwrap(),
|
DateTime::new(2f32, 2018, 5, 28, 16, 6, None).unwrap(),
|
||||||
DateTime::new(2f32, 2018, 5, 28, 16, 6, -1f64).unwrap()
|
DateTime::new(2f32, 2018, 5, 28, 16, 6, None).unwrap()
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -456,16 +734,16 @@ mod tests {
|
||||||
// but they are not equal (note 1)
|
// but they are not equal (note 1)
|
||||||
assert_ne!(
|
assert_ne!(
|
||||||
DateTime::new_ymd(2018, 5, 28).unwrap(),
|
DateTime::new_ymd(2018, 5, 28).unwrap(),
|
||||||
DateTime::new(2f32, 2018, 5, 28, 16, 6, -1f64).unwrap()
|
DateTime::new(2f32, 2018, 5, 28, 16, 6, None).unwrap()
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_ne!(
|
assert_ne!(
|
||||||
DateTime::new(2f32, 2018, 5, 28, 16, 6, -1f64).unwrap(),
|
DateTime::new(2f32, 2018, 5, 28, 16, 6, None).unwrap(),
|
||||||
DateTime::new_ym(2018, 5).unwrap()
|
DateTime::new_ym(2018, 5).unwrap()
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_ne!(
|
assert_ne!(
|
||||||
DateTime::new(2f32, 2018, 5, 28, 16, 6, -1f64).unwrap(),
|
DateTime::new(2f32, 2018, 5, 28, 16, 6, None).unwrap(),
|
||||||
DateTime::new_y(2018).unwrap()
|
DateTime::new_y(2018).unwrap()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,26 +73,31 @@ impl<'a> Serialize for DateTime {
|
||||||
let variant = if self.has_second() {
|
let variant = if self.has_second() {
|
||||||
DateTimeVariants::YMDhmsTz(
|
DateTimeVariants::YMDhmsTz(
|
||||||
self.get_year(),
|
self.get_year(),
|
||||||
self.get_month(),
|
self.get_month().unwrap(),
|
||||||
self.get_day(),
|
self.get_day().unwrap(),
|
||||||
self.get_hour(),
|
self.get_hour().unwrap(),
|
||||||
self.get_minute(),
|
self.get_minute().unwrap(),
|
||||||
f64::from(self.get_second()) + f64::from(self.get_microsecond()) / 1_000_000f64,
|
f64::from(self.get_second().unwrap())
|
||||||
self.get_time_zone_offset(),
|
+ f64::from(self.get_microsecond().unwrap()) / 1_000_000f64,
|
||||||
|
self.get_time_zone_offset().unwrap(),
|
||||||
)
|
)
|
||||||
} else if self.has_time() {
|
} else if self.has_time() {
|
||||||
DateTimeVariants::YMDhmTz(
|
DateTimeVariants::YMDhmTz(
|
||||||
self.get_year(),
|
self.get_year(),
|
||||||
self.get_month(),
|
self.get_month().unwrap(),
|
||||||
self.get_day(),
|
self.get_day().unwrap(),
|
||||||
self.get_hour(),
|
self.get_hour().unwrap(),
|
||||||
self.get_minute(),
|
self.get_minute().unwrap(),
|
||||||
self.get_time_zone_offset(),
|
self.get_time_zone_offset().unwrap(),
|
||||||
)
|
)
|
||||||
} else if self.has_day() {
|
} else if self.has_day() {
|
||||||
DateTimeVariants::YMD(self.get_year(), self.get_month(), self.get_day())
|
DateTimeVariants::YMD(
|
||||||
|
self.get_year(),
|
||||||
|
self.get_month().unwrap(),
|
||||||
|
self.get_day().unwrap(),
|
||||||
|
)
|
||||||
} else if self.has_month() {
|
} else if self.has_month() {
|
||||||
DateTimeVariants::YM(self.get_year(), self.get_month())
|
DateTimeVariants::YM(self.get_year(), self.get_month().unwrap())
|
||||||
} else if self.has_year() {
|
} else if self.has_year() {
|
||||||
DateTimeVariants::Y(self.get_year())
|
DateTimeVariants::Y(self.get_year())
|
||||||
} else {
|
} else {
|
||||||
|
@ -152,7 +157,7 @@ impl TryFrom<DateTimeVariants> for DateTime {
|
||||||
DateTimeVariants::YM(y, m) => DateTime::new_ym(y, m),
|
DateTimeVariants::YM(y, m) => DateTime::new_ym(y, m),
|
||||||
DateTimeVariants::YMD(y, m, d) => DateTime::new_ymd(y, m, d),
|
DateTimeVariants::YMD(y, m, d) => DateTime::new_ymd(y, m, d),
|
||||||
DateTimeVariants::YMDhmTz(y, m, d, h, mn, tz) => {
|
DateTimeVariants::YMDhmTz(y, m, d, h, mn, tz) => {
|
||||||
DateTime::new(tz, y, m, d, h, mn, -1f64)
|
DateTime::new(tz, y, m, d, h, mn, None)
|
||||||
}
|
}
|
||||||
DateTimeVariants::YMDhmsTz(y, m, d, h, mn, s, tz) => {
|
DateTimeVariants::YMDhmsTz(y, m, d, h, mn, s, tz) => {
|
||||||
DateTime::new(tz, y, m, d, h, mn, s)
|
DateTime::new(tz, y, m, d, h, mn, s)
|
||||||
|
@ -193,7 +198,7 @@ mod tests {
|
||||||
res
|
res
|
||||||
);
|
);
|
||||||
|
|
||||||
let datetime = DateTime::new(2f32, 2018, 5, 28, 16, 6, -1f64).unwrap();
|
let datetime = DateTime::new(2f32, 2018, 5, 28, 16, 6, None).unwrap();
|
||||||
let res = ron::ser::to_string_pretty(&datetime, pretty_config.clone());
|
let res = ron::ser::to_string_pretty(&datetime, pretty_config.clone());
|
||||||
assert_eq!(Ok("YMDhmTz(2018, 5, 28, 16, 6, 2)".to_owned()), res,);
|
assert_eq!(Ok("YMDhmTz(2018, 5, 28, 16, 6, 2)".to_owned()), res,);
|
||||||
|
|
||||||
|
@ -232,7 +237,7 @@ mod tests {
|
||||||
let datetime_de: DateTime = ron::de::from_str(datetime_ron).unwrap();
|
let datetime_de: DateTime = ron::de::from_str(datetime_ron).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
datetime_de,
|
datetime_de,
|
||||||
DateTime::new(2f32, 2018, 5, 28, 16, 6, -1f64).unwrap()
|
DateTime::new(2f32, 2018, 5, 28, 16, 6, None).unwrap()
|
||||||
);
|
);
|
||||||
|
|
||||||
let datetime_ron = "YMD(2018, 5, 28)";
|
let datetime_ron = "YMD(2018, 5, 28)";
|
||||||
|
@ -257,7 +262,7 @@ mod tests {
|
||||||
let datetime_de: DateTime = ron::de::from_str(datetime_ser.as_str()).unwrap();
|
let datetime_de: DateTime = ron::de::from_str(datetime_ser.as_str()).unwrap();
|
||||||
assert_eq!(datetime_de, datetime);
|
assert_eq!(datetime_de, datetime);
|
||||||
|
|
||||||
let datetime = DateTime::new(2f32, 2018, 5, 28, 16, 6, -1f64).unwrap();
|
let datetime = DateTime::new(2f32, 2018, 5, 28, 16, 6, None).unwrap();
|
||||||
let datetime_ser = ron::ser::to_string(&datetime).unwrap();
|
let datetime_ser = ron::ser::to_string(&datetime).unwrap();
|
||||||
let datetime_de: DateTime = ron::de::from_str(datetime_ser.as_str()).unwrap();
|
let datetime_de: DateTime = ron::de::from_str(datetime_ser.as_str()).unwrap();
|
||||||
assert_eq!(datetime_de, datetime);
|
assert_eq!(datetime_de, datetime);
|
||||||
|
|
Loading…
Reference in a new issue