cursorvec/lib.rs
1//! cursorvec, vector container with built-in cursor
2//!
3//! You can move cursor next and previous with methods, which always guarantee range bounds.
4//!
5//! Since cursorvec redirects deref trait to inner container, std lib's vector methods are also
6//! applicable to cursorvec. However cursor will not be automatically updated, thus cursor might
7//! not be in range bounds. In such case, call [update_cursor](CursorVec::update_cursor) manually
8//! after or bind the methods inside cursorvec's [modify](CursorVec::modify) method.
9//!
10//! # Operation behaviours
11//!
12//! By default, cursorvec's operations never fails but return [boolean](OpResult) or [cursorstate
13//! enum](CursorState). You can change this behaviour by enabling ```strict``` feature.
14//!
15//! ```toml
16//! [dependency]
17//! cursorvec = { version = "*", features = ["strict"] }
18//! ```
19//!
20//! If strict feature is enabled, previous operations that returned boolean value will return a
21//! result with error messages. User can redirect those results and handle errors more precisely.
22//!
23//! # Usage
24//!
25//! ```rust
26//! use cursorvec::{CursorVec, CursorState};
27//!
28//! let mut vec = CursorVec::new()
29//! .with_container(vec!["first", "second", "third", "fourth", "fifth"]);
30//!
31//! // Move cursor to next and get cursor's value
32//! assert_eq!(Some(&"first"), vec.get_current().value());
33//! assert_eq!(Some(&"second"), vec.move_next_and_get().value());
34//! assert_eq!(Some(&"fifth"), vec.move_next_nth_and_get(3).value());
35//! assert_eq!(CursorState::MaxOut, vec.move_next_and_get());
36//!
37//! // Move cursor to prevous and get cursor's value
38//! assert_eq!(Some(&"fourth"), vec.move_prev_and_get().value());
39//! assert_eq!(Some(&"first"), vec.move_prev_nth_and_get(3).value());
40//! assert_eq!(CursorState::MinOut, vec.move_prev_and_get());
41//!
42//! // Reset cursor
43//! vec.set_cursor(0);
44//!
45//! // Move cursor and tries to get values regardless of cursor success
46//! assert_eq!(Some(&"fifth"), vec.move_next_nth_and_get_always(10000));
47//! assert_eq!(Some(&"first"), vec.move_prev_nth_and_get_always(10000));
48//!
49//! // Container with rotating cursor
50//! let mut vec = CursorVec::new()
51//! .rotatable(true)
52//! .with_container(vec![1, 2, 3, 4, 5, 6, 7, 8]);
53//!
54//! assert_eq!(Some(&3), vec.move_next_nth_and_get(10).value());
55//! // always is not so differnt from non-always variant if rotation is set
56//! assert_eq!(Some(&7), vec.move_next_nth_and_get_always(4));
57//!
58//! // Modify container and update cursor
59//! vec.drain(5..);
60//! vec.update_cursor();
61//!
62//! // Cursor automatically goes to available index
63//! assert_eq!(Some(&5), vec.get_current().value());
64//!
65//! // Modify without update can possibly cause out of range error
66//! vec.drain(1..);
67//! assert_eq!(CursorState::OutOfRange, vec.get_current());
68//!
69//! vec.update_cursor();
70//! assert_ne!(CursorState::OutOfRange, vec.get_current());
71//!
72//! vec.set_container(vec![1, 2, 3, 4, 5, 6, 7, 8]);
73//! vec.set_cursor(6);
74//! assert_eq!(Some(&7), vec.get_current().value());
75//!
76//! // Use modify method to automatically update cursor
77//! vec.modify(|cont| cont.retain(|num| *num % 2 == 0));
78//!
79//! // Cursor
80//! // |
81//! // vec![2, 4, 6, 8]
82//! assert_eq!(Some(3), vec.get_cursor());
83//! assert_eq!(Some(&8), vec.get_current().value());
84//! ```
85mod container;
86mod cursor;
87mod result;
88mod test;
89
90pub use container::CursorVec;
91pub use cursor::CursorState;
92pub use result::OpResult;