1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
//! Rundo is a redo / undo library for rust which can auto generate actions.
//!
//! Thanks for rust Procedural Macros, Rundo will be disign and implementation to zero-cost support undo-redo in Rust.
//! Rundo dedicated to support undo/redo transparent for user code, it's should be used painless.
//! In most case, just use rundo attrs `#[rundo]` for your data struct, that all.
//!
//!## Installation
//!
//! Add this to your `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! rundo = "0.1"
//! ```
//!
//!## Examples
//!
//! below code will show how can Rundo maight be used.
//!
//! ```
//!#![feature(proc_macro)]
//!#![feature(decl_macro)]
//!
//! extern crate rundo;
//! use rundo::prelude::*;
//!
//! #[rundo]
//! struct Point {
//!     x: f32,
//!     y: f32,
//! }
//!
//! // Note here the macro `Point`, Rundo redefine your origin Point type
//! // with the same shape, but support undo redo.
//! // You can use it as same as before, but to literal construct
//! // must use a same name macro replace.
//!
//! fn main(){
//!   let mut space = Workspace::new(Point! {x: 2.0, y: 2.0,});
//!   {
//!     // access data across get_mut will auto collect change action during its life time.
//!     *space.get_mut().x = 3.0;
//!   }
//!
//!  // x was changed to 3.0
//!  assert_eq!(*space.data.x, 3.0);
//!
//!  // x will undo to 2.0
//!  space.undo();
//!  assert_eq!(*space.data.x, 2.0);
//!
//!  // x will redo to 3.0
//!  space.redo();
//!  assert_eq!(*space.data.x, 3.0);
//! }
//! ```
//!
//! You can also manual control change action generate;
//!
//! ```
//! # #![feature(proc_macro)]
//! # #![feature(decl_macro)]
//! #
//! # extern crate rundo;
//! # use rundo::prelude::*;
//! #
//! # #[rundo]
//! # struct Point {
//! #    x: f32,
//! #    y: f32,
//! # }
//! #
//! # fn main() {
//! let mut space = Workspace::new(Point! {x: 2.0, y: 2.0,});
//! space.begin_op();       // form here all chage will be
//!                           // merge to one op until `end_op` called
//!
//! *space.get_mut().x = 5.0;
//! *space.get_mut().y = 6.0;
//! *space.get_mut().x = 3.0;
//!
//! space.end_op();        // generate op
//!
//! // only a user op will be generate
//! space.undo();
//!
//! assert_eq!(*space.data.x, 2.0);
//! assert_eq!(*space.data.y, 2.0);
//!# }
//! ```
//! [README]: https://github.com/M-Adoo/rundo#rundo

#![feature(external_doc)]
#![feature(proc_macro)]
#![feature(decl_macro)]

#[doc(include = "../readme.md")]
extern crate rundo_attrs;
extern crate rundo_types;
#[cfg(test)]
mod test;

pub mod workspace;

pub mod prelude {
    pub use rundo_attrs::*;
    pub use workspace::Workspace;
    pub use rundo_types::prelude::*;
}