Compare commits
5 Commits
ebeec7ec6b
...
0f6f4edf88
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0f6f4edf88 | ||
|
|
644f0b4c8a | ||
|
|
3531323de0 | ||
|
|
d565e9d382 | ||
|
|
f81465534e |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1 +1,2 @@
|
||||
**/*.sw*
|
||||
/target/
|
||||
|
||||
119
Cargo.lock
generated
Normal file
119
Cargo.lock
generated
Normal file
@@ -0,0 +1,119 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.70"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.193"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.193"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_yaml"
|
||||
version = "0.9.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3cc7a1570e38322cfe4154732e5110f887ea57e22b76f4bfd32b5bdd3368666c"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
"unsafe-libyaml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.39"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tsheet-cli"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_yaml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "unsafe-libyaml"
|
||||
version = "0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f28467d3e1d3c6586d8f25fa243f544f5800fec42d97032474e17222c2b75cfa"
|
||||
@@ -6,3 +6,5 @@ edition = "2021"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
serde = { version = "1.0.193", features = ["derive"] }
|
||||
serde_yaml = "0.9.27"
|
||||
|
||||
76
src/main.rs
76
src/main.rs
@@ -1,3 +1,79 @@
|
||||
use serde::{Serialize, Deserialize};
|
||||
use std::io::{Read, Write};
|
||||
use std::fs::File;
|
||||
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||
struct Storage {
|
||||
adds: Vec<Add>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||
struct Add {
|
||||
t: i64,
|
||||
add: String,
|
||||
tag: String,
|
||||
}
|
||||
|
||||
fn save_storage(path: String, storage: Storage) -> Result<(), String> {
|
||||
match File::create(path.clone()) {
|
||||
Ok(mut writer) => _save_storage(&mut writer, storage),
|
||||
Err(reason) => Err(format!("failed to open {} to save storage: {}", path, reason)),
|
||||
}
|
||||
}
|
||||
|
||||
fn _save_storage(writer: &mut dyn Write, storage: Storage) -> Result<(), String> {
|
||||
let mut w = serde_yaml::Serializer::new(writer);
|
||||
match storage.serialize(&mut w) {
|
||||
Ok(_) => Ok(()),
|
||||
Err(reason) => Err(format!("failed to serialize storage: {}", reason)),
|
||||
}
|
||||
}
|
||||
|
||||
fn load_storage(path: String) -> Result<Storage, String> {
|
||||
match File::open(path.clone()) {
|
||||
Ok(mut reader) => _load_storage(&mut reader),
|
||||
Err(reason) => Err(format!("failed to read storage {}: {}", path, reason)),
|
||||
}
|
||||
}
|
||||
|
||||
fn _load_storage(reader: &mut dyn Read) -> Result<Storage, String> {
|
||||
match serde_yaml::from_reader::<&mut dyn Read, Storage>(reader) {
|
||||
Ok(storage) => Ok(storage),
|
||||
Err(err) => Err(format!("failed to parse storage: {}", err)),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_save_load_empty() {
|
||||
let got = _load_storage(&mut "adds: []".as_bytes()).expect("failed to parse 'adds: []' storage");
|
||||
assert_eq!(got, Storage{adds: vec![]});
|
||||
|
||||
let mut w = vec![];
|
||||
_save_storage(&mut w, got).expect("failed saving storage to writer");
|
||||
assert_eq!(String::from_utf8(w).unwrap(), "adds: []\n".to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_testdata_standalone_yaml() {
|
||||
let want = Storage{adds: vec![
|
||||
Add{t: 1, add: "def".to_string(), tag: "abc".to_string()},
|
||||
Add{t: 2, add: "ghi".to_string(), tag: "".to_string()},
|
||||
]};
|
||||
assert_eq!(
|
||||
load_storage("./src/testdata/standalone.yaml".to_string()).expect("cant load standalone.yaml"),
|
||||
want,
|
||||
);
|
||||
|
||||
let mut w = vec![];
|
||||
_save_storage(&mut w, want).expect("failed saving storage to writer");
|
||||
assert_eq!(String::from_utf8(w).unwrap(), "adds:\n- t: 1\n add: def\n tag: abc\n- t: 2\n add: ghi\n tag: ''\n".to_string());
|
||||
}
|
||||
}
|
||||
|
||||
3
src/testdata/cmdline.txt
vendored
Normal file
3
src/testdata/cmdline.txt
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
$ tsheet-cli -clock-in # adds "" for the timestamp
|
||||
$ tsheet-cli -add def -tag abc # adds def with tag abc using same-day for duration OR 1h
|
||||
$ tsheet-cli -log -since YYYY-MM-DD # prints standalone.txt inclusive since given time
|
||||
9
src/testdata/standalone.txt
vendored
Normal file
9
src/testdata/standalone.txt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
- t: 1969-12-31
|
||||
d:
|
||||
adds:
|
||||
- d: 1
|
||||
add: abc
|
||||
adds:
|
||||
- def
|
||||
- d: 0
|
||||
add: ghi
|
||||
7
src/testdata/standalone.yaml
vendored
Normal file
7
src/testdata/standalone.yaml
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
adds:
|
||||
- t: 1
|
||||
add: def
|
||||
tag: abc
|
||||
- t: 2
|
||||
add: ghi
|
||||
tag: ""
|
||||
Reference in New Issue
Block a user