Merge branch 'main' into sqlstore

This commit is contained in:
dbr 2021-09-10 09:59:35 +10:00
commit 43ca0623b1
15 changed files with 176 additions and 22 deletions

View file

@ -154,11 +154,18 @@ fn named_date<Tz: TimeZone>(
move |input: &str| {
let local_today = now.with_timezone(&local).date();
let remaining = &input[input.len()..];
let day_index = local_today.weekday().num_days_from_monday();
match input {
"yesterday" => Ok((remaining, local_today - Duration::days(1))),
"today" => Ok((remaining, local_today)),
"tomorrow" => Ok((remaining, local_today + Duration::days(1))),
// TODO: lots more!
"eod" => Ok((remaining,local_today + Duration::days(1))),
"sod" => Ok((remaining,local_today)),
"eow" => Ok((remaining,local_today + Duration::days((6-day_index).into()))),
"eoww" => Ok((remaining,local_today + Duration::days((5-day_index).into()))),
"sow" => Ok((remaining,local_today + Duration::days((6-day_index).into()))),
"soww" => Ok((remaining,local_today + Duration::days((7-day_index).into()))),
_ => Err(Err::Error(Error::new(input, ErrorKind::Tag))),
}
.map(|(rem, dt)| (rem, dt.and_hms(0, 0, 0).with_timezone(&Utc)))
@ -301,6 +308,12 @@ mod test {
#[case::today_from_evening(ldt(2021, 3, 1, 21, 30, 30), "today", ld(2021, 3, 1))]
#[case::tomorrow(ld(2021, 3, 1), "tomorrow", ld(2021, 3, 2))]
#[case::tomorow_from_evening(ldt(2021, 3, 1, 21, 30, 30), "tomorrow", ld(2021, 3, 2))]
#[case::end_of_week(ld(2021,8,25,), "eow", ld(2021,8,29))]
#[case::end_of_work_week(ld(2021,8,25), "eoww", ld(2021,8,28))]
#[case::start_of_week(ld(2021,8,25), "sow", ld(2021,8,29))]
#[case::start_of_work_week(ld(2021,8,25), "soww", ld(2021,8,30))]
#[case::end_of_today(ld(2021,8,25), "eod", ld(2021,8,26))]
#[case::start_of_today(ld(2021,8,25), "sod", ld(2021,8,25))]
fn test_local_timestamp(
#[case] now: Box<dyn Fn(FixedOffset) -> DateTime<Utc>>,
#[values(*IST, *UTC_FO, *HST)] tz: FixedOffset,

View file

@ -125,7 +125,7 @@ fn get_server(settings: &Settings) -> anyhow::Result<Box<dyn Server>> {
settings.server_origin.as_ref(),
settings.encryption_secret.as_ref(),
) {
let client_key = Uuid::parse_str(&client_key)?;
let client_key = Uuid::parse_str(client_key)?;
log::debug!("Using sync-server with origin {}", origin);
log::debug!("Sync client ID: {}", client_key);

View file

@ -30,11 +30,11 @@ pub(super) fn apply_modification(
}
for tag in modification.add_tags.iter() {
task.add_tag(&tag)?;
task.add_tag(tag)?;
}
for tag in modification.remove_tags.iter() {
task.remove_tag(&tag)?;
task.remove_tag(tag)?;
}
if let Some(wait) = modification.wait {

View file

@ -31,8 +31,7 @@ For the public TaskChampion Rust API, see the `taskchampion` crate.
*/
use std::os::unix::ffi::OsStringExt;
use std::string::FromUtf8Error;
use std::ffi::OsString;
// NOTE: it's important that this 'mod' comes first so that the macros can be used in other modules
mod macros;
@ -63,8 +62,8 @@ pub fn main() -> Result<(), Error> {
// parse the command line into a vector of &str, failing if
// there are invalid utf-8 sequences.
let argv: Vec<String> = std::env::args_os()
.map(|oss| String::from_utf8(oss.into_vec()))
.collect::<Result<_, FromUtf8Error>>()
.map(|oss| oss.into_string())
.collect::<Result<_, OsString>>()
.map_err(|_| Error::for_arguments("arguments must be valid utf-8"))?;
let argv: Vec<&str> = argv.iter().map(|s| s.as_ref()).collect();

View file

@ -130,7 +130,7 @@ impl TryFrom<&toml::Value> for Report {
.map(|(i, v)| {
v.as_str()
.ok_or_else(|| anyhow!(".filter[{}]: not a string", i))
.and_then(|s| Condition::parse_str(&s))
.and_then(|s| Condition::parse_str(s))
.map_err(|e| anyhow!(".filter[{}]: {}", i, e))
})
.collect::<Result<Vec<_>>>()?,

View file

@ -97,7 +97,7 @@ impl Settings {
"server_dir",
"reports",
];
let table = table_with_keys(&config_toml, &table_keys)?;
let table = table_with_keys(config_toml, &table_keys)?;
fn get_str_cfg<F: FnOnce(String)>(
table: &Table,
@ -184,10 +184,24 @@ impl Settings {
.ok_or_else(|| anyhow!("Could not determine config file name"))?
};
let mut document = fs::read_to_string(filename.clone())
.context("Could not read existing configuration file")?
.parse::<Document>()
.context("Could not parse existing configuration file")?;
let exists = filename.exists();
// try to create the parent directory if the file does not exist
if !exists {
if let Some(dir) = filename.parent() {
fs::create_dir_all(dir)?;
}
}
// start with the existing document, or a blank document
let mut document = if exists {
fs::read_to_string(filename.clone())
.context("Could not read existing configuration file")?
.parse::<Document>()
.context("Could not parse existing configuration file")?
} else {
Document::new()
};
// set the value as the correct type
match key {