use owned values to avoid unnecessary cloning

This commit is contained in:
Dustin J. Mitchell
2022-01-06 00:17:01 +00:00
parent 63804b5652
commit 4b2ef1913a

View File

@@ -8,10 +8,10 @@ use termcolor::WriteColor;
pub(crate) fn execute<W: WriteColor>(w: &mut W, replica: &mut Replica) -> Result<(), crate::Error> { pub(crate) fn execute<W: WriteColor>(w: &mut W, replica: &mut Replica) -> Result<(), crate::Error> {
writeln!(w, "Importing tasks from stdin.")?; writeln!(w, "Importing tasks from stdin.")?;
let tasks: Vec<HashMap<String, Value>> = let mut tasks: Vec<HashMap<String, Value>> =
serde_json::from_reader(std::io::stdin()).map_err(|_| anyhow!("Invalid JSON"))?; serde_json::from_reader(std::io::stdin()).map_err(|_| anyhow!("Invalid JSON"))?;
for task_json in &tasks { for task_json in tasks.drain(..) {
import_task(w, replica, task_json)?; import_task(w, replica, task_json)?;
} }
@@ -21,9 +21,9 @@ pub(crate) fn execute<W: WriteColor>(w: &mut W, replica: &mut Replica) -> Result
/// Convert the given value to a string, failing on compound types (arrays /// Convert the given value to a string, failing on compound types (arrays
/// and objects). /// and objects).
fn stringify(v: &Value) -> anyhow::Result<String> { fn stringify(v: Value) -> anyhow::Result<String> {
Ok(match v { Ok(match v {
Value::String(ref s) => s.clone(), Value::String(s) => s,
Value::Number(n) => n.to_string(), Value::Number(n) => n.to_string(),
Value::Bool(true) => "true".to_string(), Value::Bool(true) => "true".to_string(),
Value::Bool(false) => "false".to_string(), Value::Bool(false) => "false".to_string(),
@@ -62,8 +62,7 @@ struct Annotation {
fn import_task<W: WriteColor>( fn import_task<W: WriteColor>(
w: &mut W, w: &mut W,
replica: &mut Replica, replica: &mut Replica,
// TOOD: take this by value and consume it mut task_json: HashMap<String, Value>,
task_json: &HashMap<String, Value>,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
let uuid = task_json let uuid = task_json
.get("uuid") .get("uuid")
@@ -75,7 +74,7 @@ fn import_task<W: WriteColor>(
replica.create_task(uuid)?; replica.create_task(uuid)?;
let mut description = None; let mut description = None;
for (k, v) in task_json.iter() { for (k, v) in task_json.drain() {
match k.as_ref() { match k.as_ref() {
// `id` is the working-set ID and is not stored // `id` is the working-set ID and is not stored
"id" => {} "id" => {}
@@ -88,7 +87,7 @@ fn import_task<W: WriteColor>(
// `annotations` is a sub-aray // `annotations` is a sub-aray
"annotations" => { "annotations" => {
let annotations: Vec<Annotation> = serde_json::from_value(v.clone())?; let annotations: Vec<Annotation> = serde_json::from_value(v)?;
for ann in annotations { for ann in annotations {
let k = format!("annotation_{}", ann.entry.tc_timestamp()); let k = format!("annotation_{}", ann.entry.tc_timestamp());
replica.update_task(uuid, k, Some(ann.description))?; replica.update_task(uuid, k, Some(ann.description))?;
@@ -97,7 +96,7 @@ fn import_task<W: WriteColor>(
// `depends` is a sub-aray // `depends` is a sub-aray
"depends" => { "depends" => {
let deps: Vec<String> = serde_json::from_value(v.clone())?; let deps: Vec<String> = serde_json::from_value(v)?;
for dep in deps { for dep in deps {
let k = format!("dep_{}", dep); let k = format!("dep_{}", dep);
replica.update_task(uuid, k, Some("".to_owned()))?; replica.update_task(uuid, k, Some("".to_owned()))?;
@@ -106,7 +105,7 @@ fn import_task<W: WriteColor>(
// `tags` is a sub-aray // `tags` is a sub-aray
"tags" => { "tags" => {
let tags: Vec<String> = serde_json::from_value(v.clone())?; let tags: Vec<String> = serde_json::from_value(v)?;
for tag in tags { for tag in tags {
let k = format!("tag_{}", tag); let k = format!("tag_{}", tag);
replica.update_task(uuid, k, Some("".to_owned()))?; replica.update_task(uuid, k, Some("".to_owned()))?;
@@ -115,17 +114,18 @@ fn import_task<W: WriteColor>(
// convert all datetimes -> epoch integers // convert all datetimes -> epoch integers
"end" | "entry" | "modified" | "wait" | "due" => { "end" | "entry" | "modified" | "wait" | "due" => {
let v: TwDateTime = serde_json::from_value(v.clone())?; let v: TwDateTime = serde_json::from_value(v)?;
replica.update_task(uuid, k, Some(v.tc_timestamp()))?; replica.update_task(uuid, k, Some(v.tc_timestamp()))?;
} }
// everything else is inserted directly // everything else is inserted directly
_ => { _ => {
let v = stringify(v)?; let v = stringify(v)?;
replica.update_task(uuid, k, Some(v.clone()))?;
if k == "description" { if k == "description" {
description = Some(v); // keep a copy of the description for console output
description = Some(v.clone());
} }
replica.update_task(uuid, k, Some(v))?;
} }
} }
} }
@@ -152,29 +152,29 @@ mod test {
#[test] #[test]
fn stringify_string() { fn stringify_string() {
assert_eq!(stringify(&json!("foo")).unwrap(), "foo".to_string()); assert_eq!(stringify(json!("foo")).unwrap(), "foo".to_string());
} }
#[test] #[test]
fn stringify_number() { fn stringify_number() {
assert_eq!(stringify(&json!(2.14)).unwrap(), "2.14".to_string()); assert_eq!(stringify(json!(2.14)).unwrap(), "2.14".to_string());
} }
#[test] #[test]
fn stringify_bool() { fn stringify_bool() {
assert_eq!(stringify(&json!(true)).unwrap(), "true".to_string()); assert_eq!(stringify(json!(true)).unwrap(), "true".to_string());
assert_eq!(stringify(&json!(false)).unwrap(), "false".to_string()); assert_eq!(stringify(json!(false)).unwrap(), "false".to_string());
} }
#[test] #[test]
fn stringify_null() { fn stringify_null() {
assert_eq!(stringify(&json!(null)).unwrap(), "null".to_string()); assert_eq!(stringify(json!(null)).unwrap(), "null".to_string());
} }
#[test] #[test]
fn stringify_invalid() { fn stringify_invalid() {
assert!(stringify(&json!([1])).is_err()); assert!(stringify(json!([1])).is_err());
assert!(stringify(&json!({"a": 1})).is_err()); assert!(stringify(json!({"a": 1})).is_err());
} }
#[test] #[test]
@@ -219,7 +219,7 @@ mod test {
], ],
"urgency": 4.16849 "urgency": 4.16849
}))?; }))?;
import_task(&mut w, &mut replica, &task_json)?; import_task(&mut w, &mut replica, task_json)?;
let task = replica let task = replica
.get_task(Uuid::parse_str("fa01e916-1587-4c7d-a646-f7be62be8ee7").unwrap()) .get_task(Uuid::parse_str("fa01e916-1587-4c7d-a646-f7be62be8ee7").unwrap())