6 个版本
使用旧版 Rust 2015
0.4.0 | 2016 年 2 月 19 日 |
---|---|
0.3.3 | 2016 年 2 月 6 日 |
0.3.1 | 2016 年 1 月 17 日 |
0.2.1 | 2015 年 11 月 26 日 |
#1690 in Rust 模式
用于 nl-dump
43KB
616 行
rust-enum-derive
rust-enum-derive 是一个简单的程序,可以从文本文件生成 Rust 枚举和相关特质。为了简化将 C 代码转换为 C 枚举或 C #define,允许这些文本文件看起来像 C 枚举或 C #define。
使用方法
Usage: ./rust-enum-derive <options>
A simple program for generating rust enums and associated traits from text files.
Options:
-i, --input NAME input file name (stdin if not specified)
--input_dir NAME
input directory to traverse
-o, --output NAME output directory to traverse
--output_dir NAME
output file name (stdout if not specified)
--name NAME the enum name (Name if not specified)
--derive DERIVE Which traits to derive. Ex: "Debug, PartialEq"
-h, --help print this help menu
--define parse C #define input instead of enum
-a, --all implement all of the traits (equivalent to --display
--fromprimative --fromstr)
--default implement the Default trait with the first value
--display implement the std::fmt::Display trait
--fromprimative
implement the num::traits::FromPrimitive trait
--fromstr implement the std::str::FromStr trait
--hex hexadecimal output
--pretty_fmt implement pretty_fmt()
简单示例
以下所有示例都会生成相同的代码
ZERO = 0,
ONE = 1,
TWO = 2,
ZERO,
ONE,
TWO,
#define ZERO 0
#define ONE 1
#define TWO 2
这是生成的 Rust 枚举
pub enum Name {
ZERO = 0,
ONE = 1,
TWO = 2,
}
rust-enum-derive 可以从标准输入、文件或包含文件的目录(和相关 TOML 配置)获取输入。然后可以将输出重定向到标准输出、文件或包含文件的目录。
在从目录结构获取输入的情况下,它将寻找以 ".toml" 结尾的 TOML 文件(具有以下结构
[rust-enum-derive]
name = "Name"
derive = "Debug, PartialEq"
define = false
default = false
display = false
fromprimative = false
fromstr = false
pretty_fmt = false
这些字段的含义与命令行上的含义匹配。如果您不打算更改默认(false)值,则不需要包含任何字段,但是您需要包含一个 [rust-enum-derive]
表。您还需要包含一个与您的 .toml 文件同名但以 ".in" 结尾的文件。您的 --input_dir 中的目录结构将在 --output_dir 中复制。例如
$ rust-enum-derive --input_dir ./input/ --output_dir /tmp/output--input_dir ./input/ --output_dir /tmp/output
$ tree input/
input/
├── one.in
├── one.toml
└── sub
├── two.in
└── two.toml
1 directory, 4 files
$ tree input/
input/
├── one.in
├── one.toml
└── sub
├── two.in
└── two.toml
1 directory, 4 files
$ tree /tmp/output/
/tmp/output/
├── one.rs
└── sub
└── two.rs
1 directory, 2 files
$ tree /tmp/output/
/tmp/output/
├── one.rs
└── sub
└── two.rs
1 directory, 2 files
复杂示例
例如,rust-enum-derive 可以从以下文本文件(linux/if.h)中获取
enum net_device_flags {
IFF_UP = 1<<0, /* sysfs */
IFF_BROADCAST = 1<<1, /* __volatile__ */
IFF_DEBUG = 1<<2, /* sysfs */
IFF_LOOPBACK = 1<<3, /* __volatile__ */
IFF_POINTOPOINT = 1<<4, /* __volatile__ */
IFF_NOTRAILERS = 1<<5, /* sysfs */
IFF_RUNNING = 1<<6, /* __volatile__ */
IFF_NOARP = 1<<7, /* sysfs */
IFF_PROMISC = 1<<8, /* sysfs */
IFF_ALLMULTI = 1<<9, /* sysfs */
IFF_MASTER = 1<<10, /* __volatile__ */
IFF_SLAVE = 1<<11, /* __volatile__ */
IFF_MULTICAST = 1<<12, /* sysfs */
IFF_PORTSEL = 1<<13, /* sysfs */
IFF_AUTOMEDIA = 1<<14, /* sysfs */
IFF_DYNAMIC = 1<<15, /* sysfs */
IFF_LOWER_UP = 1<<16, /* __volatile__ */
IFF_DORMANT = 1<<17, /* __volatile__ */
IFF_ECHO = 1<<18, /* __volatile__ */
};
并生成以下代码
pub enum Name {
IFF_UP = 0x1,
IFF_BROADCAST = 0x2,
IFF_DEBUG = 0x4,
IFF_LOOPBACK = 0x8,
IFF_POINTOPOINT = 0x10,
IFF_NOTRAILERS = 0x20,
IFF_RUNNING = 0x40,
IFF_NOARP = 0x80,
IFF_PROMISC = 0x100,
IFF_ALLMULTI = 0x200,
IFF_MASTER = 0x400,
IFF_SLAVE = 0x800,
IFF_MULTICAST = 0x1000,
IFF_PORTSEL = 0x2000,
IFF_AUTOMEDIA = 0x4000,
IFF_DYNAMIC = 0x8000,
IFF_LOWER_UP = 0x10000,
IFF_DORMANT = 0x20000,
IFF_ECHO = 0x40000,
}
impl ::std::str::FromStr for Name {
type Err = ();
#[allow(dead_code)]
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"IFF_UP" => Ok(Name::IFF_UP),
"IFF_BROADCAST" => Ok(Name::IFF_BROADCAST),
"IFF_DEBUG" => Ok(Name::IFF_DEBUG),
"IFF_LOOPBACK" => Ok(Name::IFF_LOOPBACK),
"IFF_POINTOPOINT" => Ok(Name::IFF_POINTOPOINT),
"IFF_NOTRAILERS" => Ok(Name::IFF_NOTRAILERS),
"IFF_RUNNING" => Ok(Name::IFF_RUNNING),
"IFF_NOARP" => Ok(Name::IFF_NOARP),
"IFF_PROMISC" => Ok(Name::IFF_PROMISC),
"IFF_ALLMULTI" => Ok(Name::IFF_ALLMULTI),
"IFF_MASTER" => Ok(Name::IFF_MASTER),
"IFF_SLAVE" => Ok(Name::IFF_SLAVE),
"IFF_MULTICAST" => Ok(Name::IFF_MULTICAST),
"IFF_PORTSEL" => Ok(Name::IFF_PORTSEL),
"IFF_AUTOMEDIA" => Ok(Name::IFF_AUTOMEDIA),
"IFF_DYNAMIC" => Ok(Name::IFF_DYNAMIC),
"IFF_LOWER_UP" => Ok(Name::IFF_LOWER_UP),
"IFF_DORMANT" => Ok(Name::IFF_DORMANT),
"IFF_ECHO" => Ok(Name::IFF_ECHO),
_ => Err( () )
}
}
}
impl Default for Name {
fn default() -> Name {
Name::IFF_UP
}
}
impl ::std::fmt::Display for Name {
#[allow(dead_code)]
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
match *self {
Name::IFF_UP => write!(f, "IFF_UP"),
Name::IFF_BROADCAST => write!(f, "IFF_BROADCAST"),
Name::IFF_DEBUG => write!(f, "IFF_DEBUG"),
Name::IFF_LOOPBACK => write!(f, "IFF_LOOPBACK"),
Name::IFF_POINTOPOINT => write!(f, "IFF_POINTOPOINT"),
Name::IFF_NOTRAILERS => write!(f, "IFF_NOTRAILERS"),
Name::IFF_RUNNING => write!(f, "IFF_RUNNING"),
Name::IFF_NOARP => write!(f, "IFF_NOARP"),
Name::IFF_PROMISC => write!(f, "IFF_PROMISC"),
Name::IFF_ALLMULTI => write!(f, "IFF_ALLMULTI"),
Name::IFF_MASTER => write!(f, "IFF_MASTER"),
Name::IFF_SLAVE => write!(f, "IFF_SLAVE"),
Name::IFF_MULTICAST => write!(f, "IFF_MULTICAST"),
Name::IFF_PORTSEL => write!(f, "IFF_PORTSEL"),
Name::IFF_AUTOMEDIA => write!(f, "IFF_AUTOMEDIA"),
Name::IFF_DYNAMIC => write!(f, "IFF_DYNAMIC"),
Name::IFF_LOWER_UP => write!(f, "IFF_LOWER_UP"),
Name::IFF_DORMANT => write!(f, "IFF_DORMANT"),
Name::IFF_ECHO => write!(f, "IFF_ECHO"),
}
}
}
impl ::num::traits::FromPrimitive for Name {
#[allow(dead_code)]
fn from_i64(n: i64) -> Option<Self> {
match n {
0x1 => Some(Name::IFF_UP),
0x2 => Some(Name::IFF_BROADCAST),
0x4 => Some(Name::IFF_DEBUG),
0x8 => Some(Name::IFF_LOOPBACK),
0x10 => Some(Name::IFF_POINTOPOINT),
0x20 => Some(Name::IFF_NOTRAILERS),
0x40 => Some(Name::IFF_RUNNING),
0x80 => Some(Name::IFF_NOARP),
0x100 => Some(Name::IFF_PROMISC),
0x200 => Some(Name::IFF_ALLMULTI),
0x400 => Some(Name::IFF_MASTER),
0x800 => Some(Name::IFF_SLAVE),
0x1000 => Some(Name::IFF_MULTICAST),
0x2000 => Some(Name::IFF_PORTSEL),
0x4000 => Some(Name::IFF_AUTOMEDIA),
0x8000 => Some(Name::IFF_DYNAMIC),
0x10000 => Some(Name::IFF_LOWER_UP),
0x20000 => Some(Name::IFF_DORMANT),
0x40000 => Some(Name::IFF_ECHO),
_ => None
}
}
#[allow(dead_code)]
fn from_u64(n: u64) -> Option<Self> {
match n {
0x1 => Some(Name::IFF_UP),
0x2 => Some(Name::IFF_BROADCAST),
0x4 => Some(Name::IFF_DEBUG),
0x8 => Some(Name::IFF_LOOPBACK),
0x10 => Some(Name::IFF_POINTOPOINT),
0x20 => Some(Name::IFF_NOTRAILERS),
0x40 => Some(Name::IFF_RUNNING),
0x80 => Some(Name::IFF_NOARP),
0x100 => Some(Name::IFF_PROMISC),
0x200 => Some(Name::IFF_ALLMULTI),
0x400 => Some(Name::IFF_MASTER),
0x800 => Some(Name::IFF_SLAVE),
0x1000 => Some(Name::IFF_MULTICAST),
0x2000 => Some(Name::IFF_PORTSEL),
0x4000 => Some(Name::IFF_AUTOMEDIA),
0x8000 => Some(Name::IFF_DYNAMIC),
0x10000 => Some(Name::IFF_LOWER_UP),
0x20000 => Some(Name::IFF_DORMANT),
0x40000 => Some(Name::IFF_ECHO),
_ => None
}
}
}
impl Name {
fn pretty_fmt(f: &mut ::std::fmt::Formatter, flags: u32) -> ::std::fmt::Result {
let mut shift: u32 = 0;
let mut result: u32 = 1<<shift;
let mut found = false;
while result <= Name::IFF_ECHO as u32 {
let tmp = result & flags;
if tmp > 0 {
if found {
try!(write!(f, "|"));
}
let flag = Name::from_u32(tmp).unwrap();
try!(write!(f, "{}", flag));
found = true;
}
shift += 1;
result = 1<<shift;
}
write!(f, "")
}
}pub enum Name {
IFF_UP = 0x1,
IFF_BROADCAST = 0x2,
IFF_DEBUG = 0x4,
IFF_LOOPBACK = 0x8,
IFF_POINTOPOINT = 0x10,
IFF_NOTRAILERS = 0x20,
IFF_RUNNING = 0x40,
IFF_NOARP = 0x80,
IFF_PROMISC = 0x100,
IFF_ALLMULTI = 0x200,
IFF_MASTER = 0x400,
IFF_SLAVE = 0x800,
IFF_MULTICAST = 0x1000,
IFF_PORTSEL = 0x2000,
IFF_AUTOMEDIA = 0x4000,
IFF_DYNAMIC = 0x8000,
IFF_LOWER_UP = 0x10000,
IFF_DORMANT = 0x20000,
IFF_ECHO = 0x40000,
}
impl ::std::str::FromStr for Name {
type Err = ();
#[allow(dead_code)]
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"IFF_UP" => Ok(Name::IFF_UP),
"IFF_BROADCAST" => Ok(Name::IFF_BROADCAST),
"IFF_DEBUG" => Ok(Name::IFF_DEBUG),
"IFF_LOOPBACK" => Ok(Name::IFF_LOOPBACK),
"IFF_POINTOPOINT" => Ok(Name::IFF_POINTOPOINT),
"IFF_NOTRAILERS" => Ok(Name::IFF_NOTRAILERS),
"IFF_RUNNING" => Ok(Name::IFF_RUNNING),
"IFF_NOARP" => Ok(Name::IFF_NOARP),
"IFF_PROMISC" => Ok(Name::IFF_PROMISC),
"IFF_ALLMULTI" => Ok(Name::IFF_ALLMULTI),
"IFF_MASTER" => Ok(Name::IFF_MASTER),
"IFF_SLAVE" => Ok(Name::IFF_SLAVE),
"IFF_MULTICAST" => Ok(Name::IFF_MULTICAST),
"IFF_PORTSEL" => Ok(Name::IFF_PORTSEL),
"IFF_AUTOMEDIA" => Ok(Name::IFF_AUTOMEDIA),
"IFF_DYNAMIC" => Ok(Name::IFF_DYNAMIC),
"IFF_LOWER_UP" => Ok(Name::IFF_LOWER_UP),
"IFF_DORMANT" => Ok(Name::IFF_DORMANT),
"IFF_ECHO" => Ok(Name::IFF_ECHO),
_ => Err( () )
}
}
}
impl Default for Name {
fn default() -> Name {
Name::IFF_UP
}
}
impl ::std::fmt::Display for Name {
#[allow(dead_code)]
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
match *self {
Name::IFF_UP => write!(f, "IFF_UP"),
Name::IFF_BROADCAST => write!(f, "IFF_BROADCAST"),
Name::IFF_DEBUG => write!(f, "IFF_DEBUG"),
Name::IFF_LOOPBACK => write!(f, "IFF_LOOPBACK"),
Name::IFF_POINTOPOINT => write!(f, "IFF_POINTOPOINT"),
Name::IFF_NOTRAILERS => write!(f, "IFF_NOTRAILERS"),
Name::IFF_RUNNING => write!(f, "IFF_RUNNING"),
Name::IFF_NOARP => write!(f, "IFF_NOARP"),
Name::IFF_PROMISC => write!(f, "IFF_PROMISC"),
Name::IFF_ALLMULTI => write!(f, "IFF_ALLMULTI"),
Name::IFF_MASTER => write!(f, "IFF_MASTER"),
Name::IFF_SLAVE => write!(f, "IFF_SLAVE"),
Name::IFF_MULTICAST => write!(f, "IFF_MULTICAST"),
Name::IFF_PORTSEL => write!(f, "IFF_PORTSEL"),
Name::IFF_AUTOMEDIA => write!(f, "IFF_AUTOMEDIA"),
Name::IFF_DYNAMIC => write!(f, "IFF_DYNAMIC"),
Name::IFF_LOWER_UP => write!(f, "IFF_LOWER_UP"),
Name::IFF_DORMANT => write!(f, "IFF_DORMANT"),
Name::IFF_ECHO => write!(f, "IFF_ECHO"),
}
}
}
impl ::num::traits::FromPrimitive for Name {
#[allow(dead_code)]
fn from_i64(n: i64) -> Option<Self> {
match n {
0x1 => Some(Name::IFF_UP),
0x2 => Some(Name::IFF_BROADCAST),
0x4 => Some(Name::IFF_DEBUG),
0x8 => Some(Name::IFF_LOOPBACK),
0x10 => Some(Name::IFF_POINTOPOINT),
0x20 => Some(Name::IFF_NOTRAILERS),
0x40 => Some(Name::IFF_RUNNING),
0x80 => Some(Name::IFF_NOARP),
0x100 => Some(Name::IFF_PROMISC),
0x200 => Some(Name::IFF_ALLMULTI),
0x400 => Some(Name::IFF_MASTER),
0x800 => Some(Name::IFF_SLAVE),
0x1000 => Some(Name::IFF_MULTICAST),
0x2000 => Some(Name::IFF_PORTSEL),
0x4000 => Some(Name::IFF_AUTOMEDIA),
0x8000 => Some(Name::IFF_DYNAMIC),
0x10000 => Some(Name::IFF_LOWER_UP),
0x20000 => Some(Name::IFF_DORMANT),
0x40000 => Some(Name::IFF_ECHO),
_ => None
}
}
#[allow(dead_code)]
fn from_u64(n: u64) -> Option<Self> {
match n {
0x1 => Some(Name::IFF_UP),
0x2 => Some(Name::IFF_BROADCAST),
0x4 => Some(Name::IFF_DEBUG),
0x8 => Some(Name::IFF_LOOPBACK),
0x10 => Some(Name::IFF_POINTOPOINT),
0x20 => Some(Name::IFF_NOTRAILERS),
0x40 => Some(Name::IFF_RUNNING),
0x80 => Some(Name::IFF_NOARP),
0x100 => Some(Name::IFF_PROMISC),
0x200 => Some(Name::IFF_ALLMULTI),
0x400 => Some(Name::IFF_MASTER),
0x800 => Some(Name::IFF_SLAVE),
0x1000 => Some(Name::IFF_MULTICAST),
0x2000 => Some(Name::IFF_PORTSEL),
0x4000 => Some(Name::IFF_AUTOMEDIA),
0x8000 => Some(Name::IFF_DYNAMIC),
0x10000 => Some(Name::IFF_LOWER_UP),
0x20000 => Some(Name::IFF_DORMANT),
0x40000 => Some(Name::IFF_ECHO),
_ => None
}
}
}
impl Name {
fn pretty_fmt(f: &mut ::std::fmt::Formatter, flags: u32) -> ::std::fmt::Result {
let mut shift: u32 = 0;
let mut result: u32 = 1<<shift;
let mut found = false;
while result <= Name::IFF_ECHO as u32 {
let tmp = result & flags;
if tmp > 0 {
if found {
try!(write!(f, "|"));
}
let flag = Name::from_u32(tmp).unwrap();
try!(write!(f, "{}", flag));
found = true;
}
shift += 1;
result = 1<<shift;
}
write!(f, "")
}
}
您可以选择让 rust-enum-derive 实现全部、部分或没有任何方法/特质。
依赖项
~4.5MB
~90K SLoC