use super::funejson::Value; use super::todo_item::Todo; use super::todo_item_validate_todo::{todos_from_value, todos_to_value}; use super::todo_list_update_todo::index_of_todo; /// Move a todo to `to_index` in manual order (order ascending, ties by array /// position, which need not already be sorted) and renumber every order 0 to /// n-1. The result is in that manual order. /// /// # Panics /// On an unknown id or a `to_index` outside 0..n-1. pub fn move_todo(todos: &[Todo], id: &str, to_index: i64) -> Vec { let from = index_of_todo(todos, id); let last = todos.len() as i64 - 1; if to_index < 0 || to_index > last { panic!("toIndex must be between 0 and {}, received {}", last, to_index); } let mut positions: Vec = (0..todos.len()).collect(); positions.sort_by_key(|&i| (todos[i].order, i)); positions.retain(|&i| i != from); positions.insert(to_index as usize, from); positions .iter() .enumerate() .map(|(n, &i)| { let mut t = todos[i].clone(); t.order = n as i64; t }) .collect() } pub fn fune_vector(args: &[Value]) -> Value { let todos = todos_from_value(&args[0]); if let Value::Float(f) = &args[2] { panic!("toIndex must be between 0 and {}, received {}", todos.len() as i64 - 1, f); } todos_to_value(&move_todo(&todos, args[1].as_str(), args[2].as_i64())) }