Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update der requirement from 0.6.1 to 0.7.8 #252

Merged
merged 10 commits into from
Dec 30, 2023
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
**/*.rs.bk
Cargo.lock
.env
.venv
dist/
34 changes: 23 additions & 11 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "hifitime"
version = "3.8.6"
version = "3.8.7"
authors = ["Christopher Rabotin <[email protected]>"]
description = "Ultra-precise date and time handling in Rust for scientific applications with leap second support"
homepage = "https://nyxspace.com/"
Expand All @@ -20,7 +20,7 @@ name = "hifitime"
[dependencies]
serde = { version = "1.0.155", optional = true }
serde_derive = { version = "1.0.155", optional = true }
der = { version = "0.6.1", features = ["derive", "real"], optional = true }
der = { version = "0.7.8", features = ["derive", "real"], optional = true }
pyo3 = { version = "0.20.0", features = ["extension-module"], optional = true }
num-traits = { version = "0.2.15", default-features = false, features = [
"libm",
Expand All @@ -34,19 +34,31 @@ tabled = { version = "0.15.0", optional = true }
openssl = { version = "0.10", features = ["vendored"], optional = true }

[target.wasm32-unknown-unknown.dependencies]
js-sys = { version = "0.3"}
wasm-bindgen_rs = { package = "wasm-bindgen", version = "0.2"}
web-sys = { version = "0.3", features = ['Window', 'Performance', 'PerformanceTiming'] }
js-sys = { version = "0.3" }
wasm-bindgen_rs = { package = "wasm-bindgen", version = "0.2" }
web-sys = { version = "0.3", features = [
'Window',
'Performance',
'PerformanceTiming',
] }

[target.wasm32-unknown-emscripten.dependencies]
js-sys = { version = "0.3"}
wasm-bindgen_rs = { package = "wasm-bindgen", version = "0.2"}
web-sys = { version = "0.3", features = ['Window', 'Performance', 'PerformanceTiming'] }
js-sys = { version = "0.3" }
wasm-bindgen_rs = { package = "wasm-bindgen", version = "0.2" }
web-sys = { version = "0.3", features = [
'Window',
'Performance',
'PerformanceTiming',
] }

[target.asmjs-unknown-emscripten.dependencies]
js-sys = { version = "0.3"}
wasm-bindgen_rs = { package = "wasm-bindgen", version = "0.2"}
web-sys = { version = "0.3", features = ['Window', 'Performance', 'PerformanceTiming'] }
js-sys = { version = "0.3" }
wasm-bindgen_rs = { package = "wasm-bindgen", version = "0.2" }
web-sys = { version = "0.3", features = [
'Window',
'Performance',
'PerformanceTiming',
] }

[dev-dependencies]
serde_json = "1.0.91"
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,10 @@ In order to provide full interoperability with NAIF, hifitime uses the NAIF algo

# Changelog

## 3.8.7

Update to der version 0.7.x.

## 3.8.5

Changes from 3.8.2 are only dependency upgrades until this release.
Expand Down
6 changes: 3 additions & 3 deletions src/asn1der.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ impl Encode for Duration {
centuries.encoded_len()? + nanoseconds.encoded_len()?
}

fn encode(&self, encoder: &mut dyn Writer) -> der::Result<()> {
fn encode(&self, encoder: &mut impl Writer) -> der::Result<()> {
let (centuries, nanoseconds) = self.to_parts();
centuries.encode(encoder)?;
nanoseconds.encode(encoder)
Expand All @@ -43,7 +43,7 @@ impl Encode for Epoch {
ts.encoded_len()? + self.to_duration().encoded_len()?
}

fn encode(&self, encoder: &mut dyn Writer) -> der::Result<()> {
fn encode(&self, encoder: &mut impl Writer) -> der::Result<()> {
let ts: u8 = self.time_scale.into();

ts.encode(encoder)?;
Expand Down Expand Up @@ -76,7 +76,7 @@ impl Encode for Unit {
converted.encoded_len()
}

fn encode(&self, encoder: &mut dyn Writer) -> der::Result<()> {
fn encode(&self, encoder: &mut impl Writer) -> der::Result<()> {
let converted: u8 = self.into();
converted.encode(encoder)
}
Expand Down
8 changes: 7 additions & 1 deletion src/duration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ pub const NANOSECONDS_PER_CENTURY: u64 = DAYS_PER_CENTURY_U64 * NANOSECONDS_PER_
#[derive(Clone, Copy, Debug, PartialOrd, Eq, Ord)]
#[repr(C)]
#[cfg_attr(feature = "python", pyclass)]
#[cfg_attr(feature = "python", pyo3(module = "hifitime"))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Duration {
pub(crate) centuries: i16,
Expand Down Expand Up @@ -694,14 +695,19 @@ impl Duration {
}
}

#[cfg(feature = "python")]
fn __getnewargs__(&self) -> Result<(String,), PyErr> {
Ok((format!("{self}"),))
}

#[cfg(feature = "python")]
fn __str__(&self) -> String {
format!("{self}")
}

#[cfg(feature = "python")]
fn __repr__(&self) -> String {
format!("{self}")
format!("{self} @ {self:p}")
}

#[cfg(feature = "python")]
Expand Down
58 changes: 58 additions & 0 deletions src/efmt/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -453,3 +453,61 @@ pub const RFC2822_LONG: Format = Format {
],
num_items: 7,
};

/// The ISO8601 format without the time scale
pub const ISO8601_STD: Format = Format {
items: [
Some(Item {
token: Token::Year,
sep_char: Some('-'),
second_sep_char: None,
optional: false,
}),
Some(Item {
token: Token::Month,
sep_char: Some('-'),
second_sep_char: None,
optional: false,
}),
Some(Item {
token: Token::Day,
sep_char: Some('T'),
second_sep_char: None,
optional: false,
}),
Some(Item {
token: Token::Hour,
sep_char: Some(':'),
second_sep_char: None,
optional: false,
}),
Some(Item {
token: Token::Minute,
sep_char: Some(':'),
second_sep_char: None,
optional: false,
}),
Some(Item {
token: Token::Second,
sep_char: Some('.'),
second_sep_char: None,
optional: false,
}),
Some(Item {
token: Token::Subsecond,
sep_char: Some(' '),
optional: false,
second_sep_char: None,
}),
None,
None,
None,
None,
None,
None,
None,
None,
None,
],
num_items: 7,
};
27 changes: 24 additions & 3 deletions src/epoch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ const CUMULATIVE_DAYS_FOR_MONTH: [u16; 12] = {
#[derive(Copy, Clone, Eq, Default)]
#[repr(C)]
#[cfg_attr(feature = "python", pyclass)]
#[cfg_attr(feature = "python", pyo3(module = "hifitime"))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Epoch {
/// An Epoch is always stored as the duration of since J1900 in the TAI time scale.
Expand Down Expand Up @@ -1687,13 +1688,13 @@ impl Epoch {

#[cfg(feature = "python")]
#[classmethod]
/// Equivalent to `datetime.strptime, refer to <https://docs.rs/hifitime/latest/hifitime/efmt/format/struct.Format.html> for format options
/// Equivalent to `datetime.strptime`, refer to <https://docs.rs/hifitime/latest/hifitime/efmt/format/struct.Format.html> for format options
fn strptime(_cls: &PyType, epoch_str: String, format_str: String) -> PyResult<Self> {
Self::from_format_str(&epoch_str, &format_str).map_err(|e| PyErr::from(e))
}

#[cfg(feature = "python")]
/// Equivalent to `datetime.strftime, refer to <https://docs.rs/hifitime/latest/hifitime/efmt/format/struct.Format.html> for format options
/// Equivalent to `datetime.strftime`, refer to <https://docs.rs/hifitime/latest/hifitime/efmt/format/struct.Format.html> for format options
fn strftime(&self, format_str: String) -> PyResult<String> {
use crate::efmt::Formatter;
let fmt = Format::from_str(&format_str)
Expand All @@ -1702,6 +1703,21 @@ impl Epoch {
Ok(format!("{}", Formatter::new(*self, fmt)))
}

#[cfg(feature = "python")]
/// Equivalent to `datetime.isoformat`, and truncated to 23 chars, refer to <https://docs.rs/hifitime/latest/hifitime/efmt/format/struct.Format.html> for format options
fn isoformat(&self) -> PyResult<String> {
Ok(self.to_isoformat())
}

#[cfg(feature = "std")]
#[must_use]
/// The standard ISO format of this epoch (six digits of subseconds), refer to <https://docs.rs/hifitime/latest/hifitime/efmt/format/struct.Format.html> for format options
pub fn to_isoformat(&self) -> String {
use crate::efmt::consts::ISO8601_STD;
use crate::efmt::Formatter;
format!("{}", Formatter::new(*self, ISO8601_STD))[..26].to_string()
}

/// Returns this epoch with respect to the time scale this epoch was created in.
/// This is needed to correctly perform duration conversions in dynamical time scales (e.g. TDB).
///
Expand Down Expand Up @@ -2673,6 +2689,11 @@ impl Epoch {
}
}

#[cfg(feature = "python")]
fn __getnewargs__(&self) -> Result<(String,), PyErr> {
Ok((format!("{self:?}"),))
}

#[cfg(feature = "python")]
#[classmethod]
fn system_now(_cls: &PyType) -> Result<Self, Errors> {
Expand All @@ -2686,7 +2707,7 @@ impl Epoch {

#[cfg(feature = "python")]
fn __repr__(&self) -> String {
format!("{self:?}")
format!("{self:?} @ {self:p}")
}

#[cfg(feature = "python")]
Expand Down
2 changes: 1 addition & 1 deletion src/leap_seconds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ impl LatestLeapSeconds {
}

fn __repr__(&self) -> String {
format!("{self:?}")
format!("{self:?} @ {self:p}")
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/leap_seconds_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ impl LeapSecondsFile {
}

fn __repr__(&self) -> String {
format!("{self:?}")
format!("{self:?} @ {self:p}")
}
}

Expand Down
19 changes: 18 additions & 1 deletion src/timeseries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ use num_traits::Float;

#[cfg(feature = "python")]
use pyo3::prelude::*;

#[cfg(feature = "python")]
use pyo3::pyclass::CompareOp;

#[cfg(feature = "python")]
use pyo3::exceptions::PyTypeError;

/*

NOTE: This is taken from itertools: https://docs.rs/itertools-num/0.1.3/src/itertools_num/linspace.rs.html#78-93 .
Expand All @@ -26,6 +33,7 @@ NOTE: This is taken from itertools: https://docs.rs/itertools-num/0.1.3/src/iter
/// An iterator of a sequence of evenly spaced Epochs.
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "python", pyclass)]
#[cfg_attr(feature = "python", pyo3(module = "hifitime"))]
pub struct TimeSeries {
start: Epoch,
duration: Duration,
Expand Down Expand Up @@ -222,6 +230,10 @@ impl TimeSeries {
}
}

fn __getnewargs__(&self) -> Result<(Epoch, Epoch, Duration, bool), PyErr> {
Ok((self.start, self.start + self.duration, self.step, self.incl))
}

fn __iter__(slf: PyRef<'_, Self>) -> PyRef<'_, Self> {
slf
}
Expand All @@ -235,7 +247,12 @@ impl TimeSeries {
}

fn __repr__(&self) -> String {
format!("{self}")
format!("{self:?} @ {self:p}")
}

#[cfg(feature = "python")]
fn __eq__(&self, other: Self) -> bool {
*self == other
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/ut1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ impl Ut1Provider {
}

fn __repr__(&self) -> String {
format!("{self}")
format!("{self:?} @ {self:p}")
}
}

Expand Down
13 changes: 13 additions & 0 deletions tests/efmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,19 @@ fn epoch_parse_with_format() {
assert_eq!(ISO8601_FLEX.parse("2015-02-07T11:22:33.0 UTC").unwrap(), e);
assert_eq!(ISO8601_FLEX.parse("2015-02-07T11:22:33").unwrap(), e);

assert_eq!(ISO8601_STD.parse("2015-02-07T11:22:33.0").unwrap(), e);

#[cfg(feature = "std")]
{
// Test an epoch that's much more precise than usual time keepers
let e_prec = Epoch::from_gregorian_utc(2015, 2, 7, 11, 22, 33, 123456789);
assert_eq!(e_prec.to_isoformat(), "2015-02-07T11:22:33.123456");
assert_ne!(
e_prec.to_isoformat(),
Formatter::new(e_prec, ISO8601).to_string()
);
}

assert_eq!(RFC3339.parse("2015-02-07T11:22:33.0 UTC").unwrap(), e);

assert!(RFC3339.parse("2018-02-13T23:08:32Z").is_ok());
Expand Down
14 changes: 13 additions & 1 deletion tests/python/test_epoch.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from hifitime import Epoch, TimeSeries, Unit, Duration
from datetime import datetime
import pickle


def test_strtime():
Expand All @@ -16,6 +17,8 @@ def test_strtime():

assert Epoch.strptime(dt_fmt, "%A, %d %B %Y %H:%M:%S") == epoch

assert pickle.loads(pickle.dumps(epoch)) == epoch


def test_utcnow():
epoch = Epoch.system_now()
Expand All @@ -40,10 +43,16 @@ def test_time_series():
)
print(time_series)

assert pickle.loads(pickle.dumps(time_series)) == time_series

for num, epoch in enumerate(time_series):
print(f"#{num}:\t{epoch}")

assert num == 10
# Once consummed, the iterator in the time series will be different,
# so the pickling will return something different
assert pickle.loads(pickle.dumps(time_series)) != time_series


def test_duration_eq():
"""
Expand All @@ -54,4 +63,7 @@ def test_duration_eq():
assert Unit.Second * 1.0 >= Duration("0 ns")
assert Unit.Second * 1.0 > Duration("0 ns")
assert Duration("0 ns") <= Unit.Second * 1.0
assert Duration("0 ns") < Unit.Second * 1.0
assert Duration("0 ns") < Unit.Second * 1.0

dur = Duration("37 min 26 s")
assert pickle.loads(pickle.dumps(dur)) == dur
Loading