mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-07-07 20:06:36 +02:00
taskchampion: Add time.utc_timestamp function.
Add a function that returns a Timestamp from an i64. One advantage is improved readability since this function is guaranteed to return a `LocalResult::Single`. Anther advantage is that it will panic if something other than a LocalResult::Single is returned by chrono, which shouldn't be possible for UTC timestamps which can't have DST ambiguity.
This commit is contained in:
parent
5a4b981b6c
commit
1c4e103904
6 changed files with 34 additions and 36 deletions
|
@ -1,7 +1,8 @@
|
|||
//! Trait implementations for a few atomic types
|
||||
|
||||
use crate::traits::*;
|
||||
use taskchampion::chrono::{offset::LocalResult, prelude::*};
|
||||
use taskchampion::chrono::{DateTime, Utc};
|
||||
use taskchampion::utc_timestamp;
|
||||
|
||||
impl PassByValue for usize {
|
||||
type RustType = usize;
|
||||
|
@ -21,9 +22,7 @@ impl PassByValue for libc::time_t {
|
|||
|
||||
unsafe fn from_ctype(self) -> Option<DateTime<Utc>> {
|
||||
if self != 0 {
|
||||
if let LocalResult::Single(ts) = Utc.timestamp_opt(self, 0) {
|
||||
return Some(ts);
|
||||
}
|
||||
return Some(utc_timestamp(self));
|
||||
}
|
||||
None
|
||||
}
|
||||
|
|
|
@ -5,8 +5,7 @@ use std::convert::TryFrom;
|
|||
use std::ops::Deref;
|
||||
use std::ptr::NonNull;
|
||||
use std::str::FromStr;
|
||||
use taskchampion::chrono::{offset::LocalResult, TimeZone, Utc};
|
||||
use taskchampion::{Annotation, Tag, Task, TaskMut, Uuid};
|
||||
use taskchampion::{utc_timestamp, Annotation, Tag, Task, TaskMut, Uuid};
|
||||
|
||||
/// A task, as publicly exposed by this library.
|
||||
///
|
||||
|
@ -760,9 +759,7 @@ pub unsafe extern "C" fn tc_task_remove_annotation(task: *mut TCTask, entry: i64
|
|||
wrap_mut(
|
||||
task,
|
||||
|task| {
|
||||
if let LocalResult::Single(ts) = Utc.timestamp_opt(entry, 0) {
|
||||
task.remove_annotation(ts)?;
|
||||
}
|
||||
task.remove_annotation(utc_timestamp(entry))?;
|
||||
Ok(TCResult::Ok)
|
||||
},
|
||||
TCResult::Error,
|
||||
|
|
|
@ -63,7 +63,7 @@ pub use errors::Error;
|
|||
pub use replica::Replica;
|
||||
pub use server::{Server, ServerConfig};
|
||||
pub use storage::StorageConfig;
|
||||
pub use task::{Annotation, Status, Tag, Task, TaskMut};
|
||||
pub use task::{utc_timestamp, Annotation, Status, Tag, Task, TaskMut};
|
||||
pub use workingset::WorkingSet;
|
||||
|
||||
/// Re-exported type from the `uuid` crate, for ease of compatibility for consumers of this crate.
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
#![allow(clippy::module_inception)]
|
||||
use chrono::prelude::*;
|
||||
|
||||
mod annotation;
|
||||
mod status;
|
||||
mod tag;
|
||||
mod task;
|
||||
mod time;
|
||||
|
||||
pub use annotation::Annotation;
|
||||
pub use status::Status;
|
||||
pub use tag::Tag;
|
||||
pub use task::{Task, TaskMut};
|
||||
|
||||
pub type Timestamp = DateTime<Utc>;
|
||||
pub use time::{utc_timestamp, Timestamp};
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
use super::tag::{SyntheticTag, TagInner};
|
||||
use super::{Annotation, Status, Tag, Timestamp};
|
||||
use super::{utc_timestamp, Annotation, Status, Tag, Timestamp};
|
||||
use crate::depmap::DependencyMap;
|
||||
use crate::errors::{Error, Result};
|
||||
use crate::replica::Replica;
|
||||
use crate::storage::TaskMap;
|
||||
use chrono::{offset::LocalResult, prelude::*};
|
||||
use chrono::prelude::*;
|
||||
use log::trace;
|
||||
use std::convert::AsRef;
|
||||
use std::convert::TryInto;
|
||||
|
@ -136,7 +136,7 @@ impl Task {
|
|||
.unwrap_or("")
|
||||
}
|
||||
|
||||
pub fn get_entry(&self) -> Option<DateTime<Utc>> {
|
||||
pub fn get_entry(&self) -> Option<Timestamp> {
|
||||
self.get_timestamp(Prop::Entry.as_ref())
|
||||
}
|
||||
|
||||
|
@ -149,7 +149,7 @@ impl Task {
|
|||
|
||||
/// Get the wait time. If this value is set, it will be returned, even
|
||||
/// if it is in the past.
|
||||
pub fn get_wait(&self) -> Option<DateTime<Utc>> {
|
||||
pub fn get_wait(&self) -> Option<Timestamp> {
|
||||
self.get_timestamp(Prop::Wait.as_ref())
|
||||
}
|
||||
|
||||
|
@ -227,15 +227,10 @@ impl Task {
|
|||
self.taskmap.iter().filter_map(|(k, v)| {
|
||||
if let Some(ts) = k.strip_prefix("annotation_") {
|
||||
if let Ok(ts) = ts.parse::<i64>() {
|
||||
if let LocalResult::Single(entry) = Utc.timestamp_opt(ts, 0) {
|
||||
return Some(Annotation {
|
||||
entry,
|
||||
description: v.to_owned(),
|
||||
});
|
||||
} else {
|
||||
// ignore an invalid timestamp
|
||||
return None;
|
||||
}
|
||||
return Some(Annotation {
|
||||
entry: utc_timestamp(ts),
|
||||
description: v.to_owned(),
|
||||
});
|
||||
}
|
||||
// note that invalid "annotation_*" are ignored
|
||||
}
|
||||
|
@ -278,7 +273,7 @@ impl Task {
|
|||
}
|
||||
|
||||
/// Get the modification time for this task.
|
||||
pub fn get_modified(&self) -> Option<DateTime<Utc>> {
|
||||
pub fn get_modified(&self) -> Option<Timestamp> {
|
||||
self.get_timestamp(Prop::Modified.as_ref())
|
||||
}
|
||||
|
||||
|
@ -313,12 +308,10 @@ impl Task {
|
|||
|| key.starts_with("dep_")
|
||||
}
|
||||
|
||||
fn get_timestamp(&self, property: &str) -> Option<DateTime<Utc>> {
|
||||
fn get_timestamp(&self, property: &str) -> Option<Timestamp> {
|
||||
if let Some(ts) = self.taskmap.get(property) {
|
||||
if let Ok(ts) = ts.parse() {
|
||||
if let LocalResult::Single(entry) = Utc.timestamp_opt(ts, 0) {
|
||||
return Some(entry);
|
||||
}
|
||||
return Some(utc_timestamp(ts));
|
||||
}
|
||||
// if the value does not parse as an integer, default to None
|
||||
}
|
||||
|
@ -366,15 +359,15 @@ impl<'r> TaskMut<'r> {
|
|||
self.set_string(Prop::Priority.as_ref(), Some(priority))
|
||||
}
|
||||
|
||||
pub fn set_entry(&mut self, entry: Option<DateTime<Utc>>) -> Result<()> {
|
||||
pub fn set_entry(&mut self, entry: Option<Timestamp>) -> Result<()> {
|
||||
self.set_timestamp(Prop::Entry.as_ref(), entry)
|
||||
}
|
||||
|
||||
pub fn set_wait(&mut self, wait: Option<DateTime<Utc>>) -> Result<()> {
|
||||
pub fn set_wait(&mut self, wait: Option<Timestamp>) -> Result<()> {
|
||||
self.set_timestamp(Prop::Wait.as_ref(), wait)
|
||||
}
|
||||
|
||||
pub fn set_modified(&mut self, modified: DateTime<Utc>) -> Result<()> {
|
||||
pub fn set_modified(&mut self, modified: Timestamp) -> Result<()> {
|
||||
self.set_timestamp(Prop::Modified.as_ref(), Some(modified))
|
||||
}
|
||||
|
||||
|
@ -548,7 +541,7 @@ impl<'r> TaskMut<'r> {
|
|||
self.set_value(property, value)
|
||||
}
|
||||
|
||||
fn set_timestamp(&mut self, property: &str, value: Option<DateTime<Utc>>) -> Result<()> {
|
||||
fn set_timestamp(&mut self, property: &str, value: Option<Timestamp>) -> Result<()> {
|
||||
self.set_string(property, value.map(|v| v.timestamp().to_string()))
|
||||
}
|
||||
|
||||
|
|
11
taskchampion/taskchampion/src/task/time.rs
Normal file
11
taskchampion/taskchampion/src/task/time.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
use chrono::{offset::LocalResult, DateTime, TimeZone, Utc};
|
||||
|
||||
pub type Timestamp = DateTime<Utc>;
|
||||
|
||||
pub fn utc_timestamp(secs: i64) -> Timestamp {
|
||||
match Utc.timestamp_opt(secs, 0) {
|
||||
LocalResult::Single(tz) => tz,
|
||||
// The other two variants are None and Ambiguous, which both are caused by DST.
|
||||
_ => unreachable!("We're requesting UTC so daylight saving time isn't a factor."),
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue