Functional Weave
Code in Rust

todo.merge@1.0.0

README.md

1,659 bytes · view raw

# todo.merge

Merges todos brought in from elsewhere (an imported CSV file, another
device) into a list, by id, instead of replacing the whole list.

| id is in | result |
| --- | --- |
| both lists | the **incoming** todo, in the place the current one had |
| only `current` | kept as it is |
| only `incoming` | appended after the current todos |

## Which copy wins

The incoming one. A todo (todo.item) records when it was created and
completed but not when it was last edited, so there is no honest way to
tell which of two copies is newer. Importing a file is the person saying
"these are the versions I want", so the file's row is treated as the newer
copy: every field comes from it, done state and timestamps included.

## Order

The result is in manual order (todo.sort's `manual`: `order` ascending,
ties by array position), renumbered 0 to n-1, as todo.list's `moveTodo`
leaves a list:

1. The current todos in their manual order, each replaced by its incoming
   copy where there is one. A replaced todo keeps its **current** position:
   the person arranged this list, and the file's `order` is a position in a
   different list.
2. Then the todos only in `incoming`, in the incoming list's own manual
   order, so a file's order among its new rows is kept.

So a new todo whose file `order` is 0 still goes after the existing ones,
and gaps in the current orders close up.

## Errors

An id that appears twice in either list is an error
(`duplicate id "a" in the incoming list`), because it is ambiguous which
copy to keep. The todos are not otherwise checked: todo.import-csv has
already checked a file's rows with todo.item's `validateTodo`.