#invariants #borrowed #mutably #called #contract-programming

mut_guard

在某个数据被可变借用后运行一个函数

1 个不稳定版本

使用旧的 Rust 2015

0.1.0 2018 年 11 月 10 日

#422 in 内存管理

MIT 许可证

11KB
167

MutGuard

LICENSE Build Status Coverage Status Crates.io Version Documentation

此库允许你在某些数据被可变借用后调用一个函数。

注意:该函数将由 Drop 处理器调用

用例

不变性检查

它可以用来强制执行不变性:每次从元素的方法定义或从外部代码直接访问公共成员获得 &mut 时,都会运行不变性检查并验证数据是否正确。

extern crate mut_guard;
use mut_guard::*;

#[derive(Debug)]
struct LessThan20(pub u8);

impl Guard for LessThan20 {
  fn finish(&mut self) {
    assert!(self.0 <= 20, "invariant failed, internal value is too large: {}", self.0);
  }
}

fn main() {
  let mut val = MutGuard::new(LessThan20(0));

  //"val: 0"
  println!("val: {:?}", *val);

  // this would fail because MutGuard does not implement DerefMut directly
  //val.0 = 10;

  // use the guard() method to get a `&mut LessThan20`
  val.guard().0 = 10;

  //"val: 10"
  println!("val: {:?}", *val);

  // once the value returned by guard() is dropped, the invariant will be checked
  // This code will panic with the following message:
  // 'invariant failed, internal value is too large: 30'
  val.guard().0 = 30;
}

日志记录

由于保护器将在每次可变访问时被调用,我们可以在那里记录更改

# extern crate mut_guard;
# use mut_guard::*;
#
# fn main() {
  let v = Vec::new();

  // the wrap methods allows us to Specifiesy a closure instead of manually
  // implementing Guard
  let mut iv = MutGuard::wrap(v, |ref mut vec| {
    println!("vector content is now {:?}", vec);
  });

  iv.guard().push(1);
  // prints "vector content is now [1]"

  iv.guard().push(2);
  // prints "vector content is now [1, 2]"

  iv.guard().push(3);
  // prints "vector content is now [1, 2, 3]"
# }

序列化

保护函数可以用作在每次更改后将元素存储到文件中。

#[macro_use]
extern crate serde_derive;
extern crate mut_guard;
extern crate serde;
extern crate serde_json;

use mut_guard::*;
use std::fs::File;

#[derive(Serialize, Debug)]
struct Data {
    pub a: u32,
    pub s: String,
    pub v: Vec<u32>,
}

impl Guard for Data {
    fn finish(&mut self) {
        File::create("data.json")
            .map_err(|e| {
                println!("could not create data file");
            })
            .and_then(|mut f| {
                serde_json::to_writer(f, self).map_err(|e| {
                    println!("could not serialize data: {:?}", e);
                })
            });
    }
}

fn main() {
    let mut data = MutGuard::new(Data {
        a: 0,
        s: "hello".to_string(),
        v: vec![1, 2],
    });

    data.guard().s = "Hello world".to_string();
    // data.json was created and now contains:
    // {"a":0,"s":"Hello world","v":[1,2]}
}

无运行时依赖