refactor: replace time with jiff

Also updates the `timedatectl` example from `chrono` to `jiff`.
This commit is contained in:
Vukašin Vojinović 2026-03-13 14:17:49 +01:00 committed by Michael Murphy
parent 0fa672f8da
commit cc80763ffc
10 changed files with 41 additions and 46 deletions

View file

@ -9,7 +9,7 @@ license = "MPL-2.0"
futures-util.workspace = true
serde.workspace = true
thiserror.workspace = true
time.workspace = true
jiff.workspace = true
zbus.workspace = true
zvariant.workspace = true

View file

@ -43,7 +43,7 @@ async fn main() -> Result<()> {
.await
.into_diagnostic()
.wrap_err_with(|| format!("Failed to get position for media player '{}'", name))?
.map(|s| format!("{} seconds", s.as_seconds_f32()))
.map(|s| format!("{} seconds", s.as_secs_f32()))
.unwrap_or_else(|| "N/A".to_owned());
println!("\tPosition: {}", position);
if !player

View file

@ -1,11 +1,11 @@
// SPDX-License-Identifier: MPL-2.0
use crate::error::{Error, Result};
use jiff::{SignedDuration, Timestamp};
use std::{
collections::HashMap,
fmt,
ops::{Deref, DerefMut},
};
use time::{Duration, OffsetDateTime};
use zbus::zvariant::{OwnedObjectPath, Value as ZValue};
#[derive(Debug, Clone, PartialEq)]
@ -90,7 +90,7 @@ impl Metadata {
}
/// `xesam:contentCreated`: When the track was created. Usually only the year component will be useful.
pub fn created(&self) -> Option<OffsetDateTime> {
pub fn created(&self) -> Option<Timestamp> {
self.inner
.get("xesam:contentCreated")
.cloned()
@ -106,7 +106,7 @@ impl Metadata {
}
/// `xesam:firstUsed`: When the track was first played.
pub fn first_played(&self) -> Option<OffsetDateTime> {
pub fn first_played(&self) -> Option<Timestamp> {
self.inner
.get("xesam:firstUsed")
.cloned()
@ -128,7 +128,7 @@ impl Metadata {
}
/// `xesam:lastUsed`: When the track was last played.
pub fn last_played(&self) -> Option<OffsetDateTime> {
pub fn last_played(&self) -> Option<Timestamp> {
self.inner
.get("xesam:lastUsed")
.cloned()
@ -199,7 +199,7 @@ impl Metadata {
}
/// `mpris:length`: The length of the track in microseconds.
pub fn length(&self) -> Option<Duration> {
pub fn length(&self) -> Option<SignedDuration> {
self.inner
.get("mpris:length")
.cloned()
@ -209,7 +209,7 @@ impl Metadata {
MetadataValue::Str(s) => s.parse().ok(),
_ => None,
})
.map(Duration::microseconds)
.map(SignedDuration::from_micros)
}
/// `mpris:artUrl`: The location of an image representing the track or album.
@ -309,17 +309,13 @@ impl MetadataValue {
/// Tries to extract a date/time from the variant,
/// returning an error if the variant is not a date/time.
pub fn try_into_date(self) -> Result<OffsetDateTime> {
pub fn try_into_date(self) -> Result<Timestamp> {
let variant = self.variant();
match self {
MetadataValue::Str(s) => {
OffsetDateTime::parse(&s, &time::format_description::well_known::Rfc3339).map_err(
|_| Error::IncorrectVariant {
wanted: "String (DateTime)",
actual: variant,
},
)
}
MetadataValue::Str(s) => s.parse::<Timestamp>().map_err(|_| Error::IncorrectVariant {
wanted: "String (DateTime)",
actual: variant,
}),
_ => Err(Error::IncorrectVariant {
wanted: "String (DateTime)",
actual: variant,
@ -329,7 +325,7 @@ impl MetadataValue {
/// Tries to extract a date/time from the variant,
/// panicking if the variant is not a date/time.
pub fn into_date(self) -> OffsetDateTime {
pub fn into_date(self) -> Timestamp {
self.try_into_date().unwrap_or_else(|err| panic!("{}", err))
}

View file

@ -7,12 +7,12 @@ use crate::{
metadata::Metadata,
track::TrackId,
};
use jiff::SignedDuration;
use std::{
fmt::{self, Display},
ops::Deref,
str::FromStr,
};
use time::Duration;
use zbus::{Connection, names::OwnedBusName};
#[derive(Debug, Clone)]
@ -41,11 +41,9 @@ impl Player {
}
/// Seeks the specified duration.
pub async fn seek(&self, duration: Duration) -> Result<bool> {
pub async fn seek(&self, duration: SignedDuration) -> Result<bool> {
if self.proxy.can_seek().await? {
self.proxy
.seek(duration.whole_microseconds() as i64)
.await?;
self.proxy.seek(duration.as_micros() as i64).await?;
Ok(true)
} else {
Ok(false)
@ -55,9 +53,9 @@ impl Player {
/// Sets the current track position.
///
/// If `track` does not match the id of the currently-playing track, the call is ignored as "stale".
pub async fn set_position(&self, track: &TrackId, position: Duration) -> Result<()> {
pub async fn set_position(&self, track: &TrackId, position: SignedDuration) -> Result<()> {
self.proxy
.set_position(track, position.whole_microseconds() as i64)
.set_position(track, position.as_micros() as i64)
.await
.map_err(Error::from)
}
@ -65,8 +63,8 @@ impl Player {
/// How far into the current track the player is.
///
/// Not all players support this, and it will return None if this is the case.
pub async fn position(&self) -> Result<Option<Duration>> {
handle_optional(self.proxy.position().await.map(Duration::microseconds))
pub async fn position(&self) -> Result<Option<SignedDuration>> {
handle_optional(self.proxy.position().await.map(SignedDuration::from_micros))
}
/// Gets the current playback status of the player.