parse go times with tz
parent
c7b0fc8dba
commit
74b02118bc
|
|
@ -18,15 +18,63 @@ impl Tasks {
|
|||
}
|
||||
|
||||
pub fn from_reader(r: impl std::io::Read) -> Result<Tasks, String> {
|
||||
let result = Tasks::_from_reader(r)?;
|
||||
if !result.is_legacy() {
|
||||
return Ok(result);
|
||||
}
|
||||
let mut v2 = Tasks::new();
|
||||
for k in vec!["todo", "scheduled", "done"] {
|
||||
v2.0.extend(
|
||||
result.0[0]
|
||||
.get_value(k.to_string())
|
||||
.or(Some(serde_yaml::Value::Null))
|
||||
.unwrap()
|
||||
.as_sequence()
|
||||
.or(Some(&vec![]))
|
||||
.unwrap()
|
||||
.iter()
|
||||
.map(|v| {
|
||||
Task::from_value(match k {
|
||||
"done" => {
|
||||
let mut t = Task::new();
|
||||
t.set_value(
|
||||
"_done".to_string(),
|
||||
v.clone(),
|
||||
);
|
||||
serde_yaml::Value::from(t.0)
|
||||
},
|
||||
_ => v.clone(),
|
||||
})
|
||||
})
|
||||
);
|
||||
}
|
||||
Ok(v2)
|
||||
}
|
||||
|
||||
fn _from_reader(mut r: impl std::io::Read) -> Result<Tasks, String> {
|
||||
let mut buff = String::new();
|
||||
match r.read_to_string(&mut buff) {
|
||||
Err(msg) => {
|
||||
return Err(format!("failed to read body: {}", msg));
|
||||
},
|
||||
_ => {}
|
||||
};
|
||||
|
||||
let mut result = Tasks::new();
|
||||
match serde_yaml::from_reader::<_, Vec<serde_yaml::Value>>(r) {
|
||||
match serde_yaml::from_str::<Vec<serde_yaml::Value>>(&buff) {
|
||||
Ok(v) => {
|
||||
result.0.extend(v.iter().map(|x| {
|
||||
Task::from_value(x.clone())
|
||||
}));
|
||||
Ok(result)
|
||||
},
|
||||
Err(msg) => Err(format!("failed to read: {}", msg)),
|
||||
Err(msg) => match Task::from_str(buff) {
|
||||
Ok(t) => {
|
||||
result.0.push(t);
|
||||
Ok(result)
|
||||
},
|
||||
Err(_) => Err(format!("failed to parse yaml: {}", msg)),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -41,6 +89,13 @@ impl Tasks {
|
|||
.collect()
|
||||
)
|
||||
}
|
||||
|
||||
fn is_legacy(&self) -> bool {
|
||||
self.len() == 1
|
||||
&& self.0[0].get_value("done".to_string()).is_some()
|
||||
&& self.0[0].get_value("scheduled".to_string()).is_some()
|
||||
&& self.0[0].get_value("todo".to_string()).is_some()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
@ -56,6 +111,20 @@ mod test_tasks {
|
|||
assert_eq!(2, tasks.due().len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_reader_legacy() {
|
||||
let tasks = Tasks::from_reader(
|
||||
std::fs::File::open("./src/testdata/legacy.yaml").expect("failed to open file")
|
||||
).expect("failed to read file");
|
||||
assert_eq!(8, tasks.len());
|
||||
assert_eq!(5, tasks.due().len());
|
||||
assert_eq!("a".to_string(), tasks.due().0[0].get("is".to_string()).expect("missing 0th is"));
|
||||
assert_eq!("b".to_string(), tasks.due().0[1].get("todo".to_string()).expect("missing 1st todo"));
|
||||
assert_eq!("c".to_string(), tasks.due().0[2].get("is".to_string()).expect("missing 2nd is"));
|
||||
assert_eq!("d".to_string(), tasks.due().0[3].get("todo".to_string()).expect("missing 3rd todo"));
|
||||
assert_eq!("e".to_string(), tasks.due().0[4].get("todo".to_string()).expect("missing 4th todo"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_reader() {
|
||||
let tasks = Tasks::from_reader(
|
||||
|
|
@ -79,8 +148,16 @@ impl Task {
|
|||
Task(serde_yaml::Mapping::new())
|
||||
}
|
||||
|
||||
pub fn from_reader(r: impl std::io::Read) -> Result<Task, String> {
|
||||
match serde_yaml::from_reader::<_, serde_yaml::Value>(r) {
|
||||
pub fn from_reader(mut r: impl std::io::Read) -> Result<Task, String> {
|
||||
let mut buff = String::new();
|
||||
match r.read_to_string(&mut buff) {
|
||||
Err(msg) => Err(format!("failed to read body: {}", msg)),
|
||||
_ => Task::from_str(buff),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_str(s: String) -> Result<Task, String> {
|
||||
match serde_yaml::from_str::<serde_yaml::Value>(&s) {
|
||||
Ok(v) => Ok(Task::from_value(v)),
|
||||
Err(msg) => Err(format!("failed to read value: {}", msg)),
|
||||
}
|
||||
|
|
@ -169,6 +246,17 @@ impl Task {
|
|||
mod test_task {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn from_str() {
|
||||
assert!(Task::from_str("{ invalid".to_string()).is_err());
|
||||
assert!(Task::from_str("1".to_string()).is_ok());
|
||||
assert!(Task::from_str("'1'".to_string()).is_ok());
|
||||
assert!(Task::from_str("null".to_string()).is_ok());
|
||||
assert!(Task::from_str("true".to_string()).is_ok());
|
||||
assert!(Task::from_str("[]".to_string()).is_ok());
|
||||
assert!(Task::from_str("{}".to_string()).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_reader() {
|
||||
let task = Task::from_reader(
|
||||
|
|
@ -483,6 +571,7 @@ impl TS {
|
|||
}
|
||||
|
||||
fn new(src: String) -> Result<TS, String> {
|
||||
// %Y-%m-%dT%H:%MZ
|
||||
match DateTime::parse_from_str(
|
||||
&format!("{} +0000", src),
|
||||
"%Y-%m-%dT%H:%MZ %z",
|
||||
|
|
@ -490,6 +579,8 @@ impl TS {
|
|||
Ok(v) => { return Ok(TS(v.timestamp() as u64)) },
|
||||
_ => {},
|
||||
};
|
||||
|
||||
// %Y-%m-%dT%H
|
||||
match NaiveDateTime::parse_from_str(
|
||||
&format!("{}:00", src),
|
||||
"%Y-%m-%dT%H:%M",
|
||||
|
|
@ -497,6 +588,8 @@ impl TS {
|
|||
Ok(v) => { return Ok(TS(v.and_utc().timestamp() as u64)) },
|
||||
_ => {},
|
||||
};
|
||||
|
||||
// %Y-%m-%d
|
||||
match NaiveDateTime::parse_from_str(
|
||||
&format!("{}T00:00", src),
|
||||
"%Y-%m-%dT%H:%M",
|
||||
|
|
@ -504,7 +597,31 @@ impl TS {
|
|||
Ok(v) => { return Ok(TS(v.and_utc().timestamp() as u64)) },
|
||||
_ => {},
|
||||
};
|
||||
Err(format!("cannot parse date format from {}", src))
|
||||
|
||||
// Sun Dec 3 23:29:27 EST 2023
|
||||
match DateTime::parse_from_str(
|
||||
&format!("{}", src)
|
||||
.replace("PDT", "-0800")
|
||||
.replace("MDT", "-0700")
|
||||
.replace("EDT", "-0400")
|
||||
.replace("PST", "-0700")
|
||||
.replace("MST", "-0600")
|
||||
.replace("EST", "-0500")
|
||||
.replace(" 1 ", " 01 ")
|
||||
.replace(" 2 ", " 02 ")
|
||||
.replace(" 3 ", " 03 ")
|
||||
.replace(" 4 ", " 04 ")
|
||||
.replace(" 5 ", " 05 ")
|
||||
.replace(" 6 ", " 06 ")
|
||||
.replace(" 7 ", " 07 ")
|
||||
.replace(" 8 ", " 08 ")
|
||||
.replace(" 9 ", " 09 ")
|
||||
.replace(" ", " "),
|
||||
"%a %b %d %H:%M:%S %z %Y",
|
||||
) {
|
||||
Ok(v) => Ok(TS(v.timestamp() as u64)),
|
||||
Err(msg) => Err(format!("failed to parse legacy golang time: {}", msg)),
|
||||
}
|
||||
}
|
||||
|
||||
fn unix(&self) -> u64 {
|
||||
|
|
@ -525,6 +642,42 @@ mod test_ts {
|
|||
|
||||
#[test]
|
||||
fn parse() {
|
||||
match TS::new("Tue Nov 7 07:33:11 PST 2023".to_string()) {
|
||||
Ok(ts) => {
|
||||
assert_eq!("2023-11-07T14:33Z", ts.to_string());
|
||||
},
|
||||
Err(err) => assert!(false, "failed to parse ts: {}", err),
|
||||
};
|
||||
match TS::new("Sun Jun 4 05:24:32 PDT 2023".to_string()) {
|
||||
Ok(ts) => {
|
||||
assert_eq!("2023-06-04T13:24Z", ts.to_string());
|
||||
},
|
||||
Err(err) => assert!(false, "failed to parse ts: {}", err),
|
||||
};
|
||||
match TS::new("Sat Nov 4 08:36:01 MDT 2023".to_string()) {
|
||||
Ok(ts) => {
|
||||
assert_eq!("2023-11-04T15:36Z", ts.to_string());
|
||||
},
|
||||
Err(err) => assert!(false, "failed to parse ts: {}", err),
|
||||
};
|
||||
match TS::new("Sun Nov 5 22:27:17 MST 2023".to_string()) {
|
||||
Ok(ts) => {
|
||||
assert_eq!("2023-11-06T04:27Z", ts.to_string());
|
||||
},
|
||||
Err(err) => assert!(false, "failed to parse ts: {}", err),
|
||||
};
|
||||
match TS::new("Thu Apr 18 16:17:41 EDT 2024".to_string()) {
|
||||
Ok(ts) => {
|
||||
assert_eq!("2024-04-18T20:17Z", ts.to_string());
|
||||
},
|
||||
Err(err) => assert!(false, "failed to parse ts: {}", err),
|
||||
};
|
||||
match TS::new("Sun Dec 3 23:29:27 EST 2023".to_string()) {
|
||||
Ok(ts) => {
|
||||
assert_eq!("2023-12-04T04:29Z", ts.to_string());
|
||||
},
|
||||
Err(err) => assert!(false, "failed to parse ts: {}", err),
|
||||
};
|
||||
match TS::new("2024-05-01T00:00Z".to_string()) {
|
||||
Ok(ts) => {
|
||||
assert_eq!(1714521600, ts.unix());
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
todo:
|
||||
- a
|
||||
- todo: b
|
||||
schedule: 2000-01-01
|
||||
scheduled:
|
||||
- c
|
||||
- todo: d
|
||||
schedule: 2000-02-01
|
||||
- todo: e
|
||||
ts: Sun Dec 3 23:29:27 EST 2023
|
||||
schedule: '0 0 1 1 *'
|
||||
- todo: f
|
||||
schedule: 2099-02-02
|
||||
done:
|
||||
- g
|
||||
- todo: h
|
||||
ts: Sun Dec 3 23:29:27 EST 2023
|
||||
Loading…
Reference in New Issue