#attributes #macro-derive #struct #accessor #boilerplate #fields #self

viewit

为结构体创建访问器的属性和派生宏

6个版本

0.1.5 2023年4月16日
0.1.4 2023年4月1日
0.1.2 2023年3月5日
0.0.1 2023年3月5日

过程宏 中排名第 1277

Download history 15/week @ 2024-03-11 1283/week @ 2024-03-18 821/week @ 2024-03-25 255/week @ 2024-04-01 613/week @ 2024-04-08 263/week @ 2024-04-15 117/week @ 2024-04-22 131/week @ 2024-04-29 4/week @ 2024-05-06 18/week @ 2024-05-13 16/week @ 2024-05-20 48/week @ 2024-05-27 22/week @ 2024-06-03 27/week @ 2024-06-10 27/week @ 2024-06-17 33/week @ 2024-06-24

每月下载量 110
11 Crates 中使用(直接使用 9 个)

Apache-2.0/MIT

38KB
795

ViewIt

ViewIt 包含一个派生宏和一个属性宏,帮助您避免编写样板代码。请参阅介绍以获取更多详细信息。

github Build

docs.rs crates.io crates.io

license-apache license-mit

介绍

默认情况下,Rust 中结构体的字段是私有的,但逐个添加字段的可见性很烦人,所以 viewit 属性宏将帮助您完成此类操作。

没有 viewit

pub struct Foo {
  pub f1: u8,
  pub f2: u16,
  pub f3: String,
  pub f4: Vec<u8>
}

viewit

use viewit::viewit;

#[viewit]
pub struct Foo {
  f1: u8,
  f2: u16,
  f3: String,
  f4: Vec<u8>
}

默认情况下,viewit 将使用结构体的可见性为每个字段,展开代码等于以下内容。

pub struct Foo {
    pub f1: u8,
    pub f2: u16,
    pub f3: String,
    pub f4: Vec<u8>,
}
impl Foo {
    #[inline]
    pub fn f1(&self) -> &u8 {
        &self.f1
    }
    #[inline]
    pub fn f2(&self) -> &u16 {
        &self.f2
    }
    #[inline]
    pub fn f3(&self) -> &String {
        &self.f3
    }
    #[inline]
    pub fn f4(&self) -> &Vec<u8> {
        &self.f4
    }
    #[inline]
    pub fn set_f1(mut self, val: u8) -> Self {
        self.f1 = val;
        self
    }
    #[inline]
    pub fn set_f2(mut self, val: u16) -> Self {
        self.f2 = val;
        self
    }
    #[inline]
    pub fn set_f3(mut self, val: String) -> Self {
        self.f3 = val;
        self
    }
    #[inline]
    pub fn set_f4(mut self, val: Vec<u8>) -> Self {
        self.f4 = val;
        self
    }
}

高级用法

viewit 提供了多个有用的配置,帮助您灵活地生成所需的内容。


use viewit::viewit;

struct FromString {
  src: String,
}

impl From<&String> for FromString {
  fn from(src: &String) -> Self {
    Self { src: src.clone() }
  }
}


fn vec_to_string(src: &[u8]) -> String {
  String::from_utf8_lossy(src).to_string()
}

#[viewit(
  // set this, then this visibility will be applied to the fields
  vis_all = "pub(crate)",
  // this will not generate setters
  setters(
    // change the prefix for all setters
    prefix = "with",
    // change the setters fn style, available values here are ref, into, tryinto or move
    style = "ref",
    // if you do not want to generate getters, you can use skip
    // skip, 
  ),
  getters(
    // change the prefix for all getters
    prefix = "get",
    // change the getters fn style, available values here are ref and move
    style = "ref",
    // if you do not want to generate getters, you can use skip
    // skip,
  ),
  // print the generated code to std out, other available values here are: stderr or "path/to/output/file"
  debug = "stdout"
)]
struct Foo {
  #[viewit(
    getter(
      style = "move",
      rename = "get_first_field",
      vis = "pub" // we can custom field getter
    ),
    setter(
      skip, // we do not want the setter for the field, then we skip it.
    )
  )]
  f1: u8,
  #[viewit(
    getter(
      skip, // we do not want the getter for the field, then we skip it
    )
  )]
  f2: u16,

  #[viewit(
    getter(
      result(
        // sometimes we may want to convert the f4 field to a generic type
        type = "T",
        converter(
          style = "ref", // take the ownership of the field
          fn = "T::from", // the fn used to do the conversion
        ),
        // set the trait bound
        bound = "T: for<'a> From<&'a String>"
      )
    )
  )]
  f3: String,

  #[viewit(
    getter(
      result(
        // we want to convert the f3 field to String
        type = "String",
        converter(
          style = "ref", // take the reference of the field
          fn = "vec_to_string" // the fn used to do the conversion
        ),
      )
    )
  )]
  f4: Vec<u8>,
}

viewit 将帮助您生成代码

struct Foo {
    pub(crate) f1: u8,
    pub(crate) f2: u16,
    pub(crate) f3: String,
    pub(crate) f4: Vec<u8>,
}
impl Foo {
    #[inline]
    pub fn get_first_field(&self) -> u8 {
        self.f1
    }
    #[inline]
    pub(crate) fn get_f3<T: for<'a> From<&'a String>>(&self) -> T {
        T::from(&self.f3)
    }
    #[inline]
    pub(crate) fn get_f4(&self) -> String {
        vec_to_string(&self.f4)
    }
    #[inline]
    pub(crate) fn with_f2(&mut self, val: u16) {
        self.f2 = val;
    }
    #[inline]
    pub(crate) fn with_f3(&mut self, val: String) {
        self.f3 = val;
    }
    #[inline]
    pub(crate) fn with_f4(&mut self, val: Vec<u8>) {
        self.f4 = val;
    }
}

许可证

根据您的选择,在 Apache 许可证,版本 2.0MIT 许可证 下授权。
除非您明确表示,否则根据 Apache-2.0 许可证的定义,您有意提交给本项目包含的任何贡献,将根据上述方式双许可,不附加任何额外条款或条件。

依赖项

~2MB
~48K SLoC