Open Mice7R opened 1 year ago
I can fix the things clippy is complaining about and the typo but what can I do with cspell? timew is the name of the program.
timew is the name of the program
Please add it to https://github.com/greshake/i3status-rust/blob/master/cspell.yaml
@notramo would you like to test this?
This thing got stuck in pending. I've implemented your suggestion and updated the code for the new api.
Wait, I've noticed there is an error when "continuing" a task
There
Looks like there's 2 small formatting issues (missing ,
s)
Diff in /home/runner/work/i3status-rust/i3status-rust/src/blocks/timewarrior.rs at line 141:
annotation: item.annotation,
start: chrono::TimeZone::from_utc_datetime(
&chrono::Utc,
- &chrono::NaiveDateTime::parse_from_str(&item.start, "%Y%m%dT%H%M%SZ").unwrap()
+ &chrono::NaiveDateTime::parse_from_str(&item.start, "%Y%m%dT%H%M%SZ").unwrap(),
),
end: item.end.map(|v| {
chrono::TimeZone::from_utc_datetime(
Diff in /home/runner/work/i3status-rust/i3status-rust/src/blocks/timewarrior.rs at line 148:
&chrono::Utc,
- &chrono::NaiveDateTime::parse_from_str(&v, "%Y%m%dT%H%M%SZ").unwrap()
+ &chrono::NaiveDateTime::parse_from_str(&v, "%Y%m%dT%H%M%SZ").unwrap(),
)
}),
}
You can avoid having to use the TimewarriorRAW
intermediate stucture like this:
diff --git a/src/blocks/timewarrior.rs b/src/blocks/timewarrior.rs
index 26d4a67c..a232e1fd 100644
--- a/src/blocks/timewarrior.rs
+++ b/src/blocks/timewarrior.rs
@@ -35,7 +35,10 @@
//! - `tasks`
use super::prelude::*;
-use chrono::DateTime;
+
+use chrono::{offset::Utc, DateTime};
+use serde::de::{self, Deserialize, Deserializer};
+use serde_with::{serde_as, DeserializeAs};
use tokio::process::Command;
#[derive(Deserialize, Debug, SmartDefault)]
@@ -112,51 +115,33 @@ pub async fn run(config: &Config, api: &CommonApi) -> Result<()> {
}
}
-/// Raw output from timew
-#[derive(Deserialize, Debug)]
-struct TimewarriorRAW {
- pub id: u32,
- pub start: String,
- pub tags: Vec<String>,
- pub annotation: Option<String>,
- pub end: Option<String>,
-}
-
/// TimeWarrior entry
+#[serde_as]
#[derive(Debug, PartialEq, Deserialize)]
-#[serde(from = "TimewarriorRAW")]
struct TimewarriorData {
pub id: u32,
- pub start: DateTime<chrono::offset::Utc>,
+ #[serde_as(as = "DateTimeAsString")]
+ pub start: DateTime<Utc>,
pub tags: Vec<String>,
pub annotation: Option<String>,
- pub end: Option<DateTime<chrono::offset::Utc>>,
+ #[serde_as(as = "Option<DateTimeAsString>")]
+ pub end: Option<DateTime<Utc>>,
}
-impl From<TimewarriorRAW> for TimewarriorData {
- fn from(item: TimewarriorRAW) -> Self {
- Self {
- id: item.id,
- tags: item.tags,
- annotation: item.annotation,
- start: chrono::TimeZone::from_utc_datetime(
- &chrono::Utc,
- &chrono::NaiveDateTime::parse_from_str(&item.start, "%Y%m%dT%H%M%SZ").unwrap()
- ),
- end: item.end.map(|v| {
- chrono::TimeZone::from_utc_datetime(
- &chrono::Utc,
- &chrono::NaiveDateTime::parse_from_str(&v, "%Y%m%dT%H%M%SZ").unwrap()
- )
- }),
- }
- }
-}
+struct DateTimeAsString;
-/// Format a DateTime given a format string
-#[allow(dead_code)]
-fn format_datetime(date: &DateTime<chrono::Utc>, format: &str) -> String {
- date.format(format).to_string()
+impl<'de> DeserializeAs<'de, DateTime<Utc>> for DateTimeAsString {
+ fn deserialize_as<D>(deserializer: D) -> Result<DateTime<Utc>, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ use chrono::NaiveDateTime;
+ use de::Error;
+
+ let s = String::deserialize(deserializer)?;
+ let dt = NaiveDateTime::parse_from_str(&s, "%Y%m%dT%H%M%SZ").map_err(D::Error::custom)?;
+ Ok(DateTime::<Utc>::from_naive_utc_and_offset(dt, Utc))
+ }
}
/// Execute "timew export now" and return the current task (if any)
Any maybe this is a stupid question, but as someone who's never used taskwarrior can you have multiple tasks at the same time?
Here's a version without using the RAW intermediate stuct:
diff --git a/src/blocks/timewarrior.rs b/src/blocks/timewarrior.rs
index 26d4a67c..2da0f92b 100644
--- a/src/blocks/timewarrior.rs
+++ b/src/blocks/timewarrior.rs
@@ -35,7 +35,9 @@
//! - `tasks`
use super::prelude::*;
-use chrono::DateTime;
+
+use chrono::{offset::Utc, DateTime};
+use serde::de::{self, Deserialize, Deserializer};
use tokio::process::Command;
#[derive(Deserialize, Debug, SmartDefault)]
@@ -68,7 +70,7 @@ pub async fn run(config: &Config, api: &CommonApi) -> Result<()> {
if let Some(tw) = data {
if tw.end.is_none() {
// only show active tasks
- let elapsed = chrono::Utc::now() - tw.start;
+ let elapsed = chrono::Utc::now() - tw.start.0;
// calculate state
for (level, st) in [
@@ -112,51 +114,31 @@ pub async fn run(config: &Config, api: &CommonApi) -> Result<()> {
}
}
-/// Raw output from timew
-#[derive(Deserialize, Debug)]
-struct TimewarriorRAW {
- pub id: u32,
- pub start: String,
- pub tags: Vec<String>,
- pub annotation: Option<String>,
- pub end: Option<String>,
-}
-
/// TimeWarrior entry
#[derive(Debug, PartialEq, Deserialize)]
-#[serde(from = "TimewarriorRAW")]
struct TimewarriorData {
pub id: u32,
- pub start: DateTime<chrono::offset::Utc>,
+ pub start: SerdeDateTime,
pub tags: Vec<String>,
pub annotation: Option<String>,
- pub end: Option<DateTime<chrono::offset::Utc>>,
+ pub end: Option<SerdeDateTime>,
}
-impl From<TimewarriorRAW> for TimewarriorData {
- fn from(item: TimewarriorRAW) -> Self {
- Self {
- id: item.id,
- tags: item.tags,
- annotation: item.annotation,
- start: chrono::TimeZone::from_utc_datetime(
- &chrono::Utc,
- &chrono::NaiveDateTime::parse_from_str(&item.start, "%Y%m%dT%H%M%SZ").unwrap()
- ),
- end: item.end.map(|v| {
- chrono::TimeZone::from_utc_datetime(
- &chrono::Utc,
- &chrono::NaiveDateTime::parse_from_str(&v, "%Y%m%dT%H%M%SZ").unwrap()
- )
- }),
- }
- }
-}
+#[derive(Debug, PartialEq)]
+struct SerdeDateTime(DateTime<Utc>);
-/// Format a DateTime given a format string
-#[allow(dead_code)]
-fn format_datetime(date: &DateTime<chrono::Utc>, format: &str) -> String {
- date.format(format).to_string()
+impl<'de> Deserialize<'de> for SerdeDateTime {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ use chrono::NaiveDateTime;
+ use de::Error;
+
+ let s = String::deserialize(deserializer)?;
+ let dt = NaiveDateTime::parse_from_str(&s, "%Y%m%dT%H%M%SZ").map_err(D::Error::custom)?;
+ Ok(Self(DateTime::<Utc>::from_naive_utc_and_offset(dt, Utc)))
+ }
}
/// Execute "timew export now" and return the current task (if any)
Any maybe this is a stupid question, but as someone who's never used taskwarrior can you have multiple tasks at the same time?
Timewarrior and Taskwarrior are 2 different programs. This PR is about Timewarrior. In Timewarrior, one period can have multiple tags, but they must be started at the same time and ended at the same time (as they are attached to one interval). If someone wants to finish one tag and continue the other, they can stop the current period then start new with only one tag.
Adds a block that displays the time of the current active task in timewarrior.
Closes #1703