2个不稳定版本
0.2.0 | 2023年11月14日 |
---|---|
0.1.0 | 2022年9月25日 |
#1657 in Rust模式
54 每月下载量
用于 2 个crate(通过 querio)
15KB
77 行
功能
🐍 将 struct 转换为元组并反向转换
🦎 将 enum 转换为元组并反向转换
🦢 获取 struct 字段的(mut)引用元组
🐓 获取 enum 字段的(mut)引用元组
🦥 忽略特定字段
🦆 递归地完成所有操作
用法
🐠 在 Cargo.toml
中添加 intuple 依赖
[dependencies]
intuple = "0.2"
🦀 在 rust 中使用/导入所有内容
use intuple::*;
🦚 多种转换方式
#[derive(Intuple)]
struct Struct {a:u32, b:u32, c:u32}
fn main(){
// use std traits
let strct: Struct = (3,2,1).into();
let tuple = <(u32, u32, u32)>::from(strct);
let strct = Struct::from((3,2,1));
let tuple: (u32, u32, u32) = strct.into();
// OR intuple trait
let strct = Struct::from_tuple((3,2,1));
let tuple = strct.into_tuple(); // or strct.intuple()
// references
let strct = Struct::from_tuple((3,2,1));
let tupref = strct.as_tuple_ref(); // (&u32,&u32,&u32)
let tupref = strct.as_tuple_ref_mut(); // (&mut u32,&mut u32,&mut u32)
*tupref.1 = 3;
}
元组类型
🦊 通过限定路径访问生成的元组类型
#[derive(Intuple)]
struct Nice {a:u32, b:u32, c:u32}
fn main(){
let tup: <Nice as Intuple>::Tuple = (3,2,1);
let tup: (u32, u32, u32) = (3,2,1); // <- same as above
// reference tuple types
let tup: <Nice as IntupleRef>::Tuple = (&3,&2,&1);
let tup: (&u32, &u32, &u32) = (&3,&2,&1); // <- same as above
// mut reference tuple types
let tup: <Nice as IntupleRef>::TupleMut = (&mut 3,&mut 2,&mut 1);
let tup: (&mut u32, &mut u32, &mut u32) = (&mut 3,&mut 2,&mut 1); // <- same as above
}
忽略
🦥 使用 #[igno]
/#[ignore]
忽略特定字段
🐻 或者 #[intuple(igno)]
/#[intuple(ignore)]
🐼 在转换为结构时,被忽略的字段需要实现 Default 特性
#[derive(Intuple)]
struct Struct {a:u32, #[igno] b:u32, c:u32}
fn main(){
let strct = Struct::from((2,1));
// => {a:2, b:0, c:1}
let tuple: (u32, u32) = strct.into();
// => (2, 1)
}
递归
🦊 使用 #[recursive]
/#[rcsv]
递归转换
🦐 或 #[intuple(rcsv)]
/#[intuple(recursive)]
🐼 递归字段需要派生 Intuple
#[derive(Intuple)]
struct Struct {a:u32, b:u32, c:u32}
#[derive(Intuple)]
struct Recursive {a:u32, #[recursive] b:Struct, c:u32}
fn main(){
let rcsv: Recursive = (9,(3,2,1),8).into();
// => Recursive{a:9, b:Struct{a:3,b:2,c:1}, c:8}
let tuple: RecursiveIntuple = rcsv.into();
// => (9,(3,2,1),8)
}
🦆 递归也可以与 .as_tuple_ref()
和 as_tuple_ref_mut()
一起使用
#[derive(Intuple)]
struct Struct {a:u32, b:u32, c:u32}
#[derive(Intuple)]
struct Recursive {a:u32, #[recursive] b:Struct, c:u32}
fn main(){
let rcsv = Recursive::from((9,(3,2,1),8));
let tuple = rcsv.as_tuple_ref();
// => (&9,(&3,&2,&1),&8)
}
枚举
🙉 将枚举转换为元组不如结构体直接,因此实现了两种方法!
🐍 1. 位置法
🐆 使用 Intuple
- 不生成额外的枚举或结构体
🐢 字段元组被包裹在 Option<>
中,这些又位于另一个元组内部
🦎 外部元组字段的数量与枚举变体的数量相同
🐊 所需的 None
变体将转换为 (None,None,None,...)
🐉 任何其他变体将占据一个槽位,具体取决于其位置 (None,Some(tuple),None,...)
// Positional
#[derive( Intuple, Debug )]
// enums require a 'None' variant
enum Enum { None, Unit, Unnamed(u32,u32), Another(u8,u8) }
fn main(){
let enum = Enum::Unnamed(1,2);
let tuple = enum.as_tuple_ref();
// => (None, Some((&1,&2)), None)
let tuple = enum.into_tuple();
// => (None, Some((1,2)), None)
let enum = Enum::None;
let tuple = rcsv.into_tuple();
// => (None,None,None)
}
🦊 2. 生成元组枚举
🐈 使用 IntupleEnum
- 将生成 三个 额外的枚举
🐕 {EnumName}Intuple
,{EnumName}IntupleRef
和 {EnumName}IntupleRefMut
🦄 这些枚举将使用原始变体名称并包含一个元组
🐔 要为它们设置派生,请使用 #[intuple(derive(...))]
⚠ 要在 任何地方 递归使用它们,请使用 #[recursive_enum]
或 #[rcsve]
🦢 .into()
/.from(..)
已实现,但自定义方法改为
🐓 .from_tuple_enum(..)
、.into_tuple_enum()
、.as_tuple_enum_ref()
和 .as_tuple_enum_ref_mut()
// Generated
#[derive( IntupleEnum, Debug )]
#[intuple(derive( Debug ))]
enum Enum { Unit, Unnamed(u32,u32), Another(u8,u8) }
fn main(){
let enum = Enum::Unnamed(1,2);
let tuple = enum.as_tuple_enum_ref();
// => EnumIntupleRef::Unnamed((&1,&2))
let tuple = enum.into_tuple_enum();
// => EnumIntupleRef::Unnamed((1,2))
}
示例:Serde - 突破思维定势
🦄 可以使用 serde
而不实现 Serialize/Deserialize
🐔 这仅适用于 位置枚举元组!
use intuple::*;
#[derive(Intuple)]
struct Named{a:u32, b:u32, c:u32, d:u32, e:u32, f:u32}
fn main(){
let named = Named::from((1,2,3,4,5,6));
let json = serde_json::to_string(&named.as_tuple_ref()).unwrap();
println!("{}",json); //=> "[1,2,3,4,5,6]"
let tuple = serde_json::from_str::<<Named as Intuple>::Tuple>(&json).unwrap();
let named_again = Named::from(tuple);
// named == named_again
}
更多信息
许可证
许可协议为 Apache License, Version 2.0 或 MIT 许可证,您可选择其一。除非您明确声明,否则您有意提交以包含在本软件包中的任何贡献,根据 Apache-2.0 许可协议定义,将双重许可如上所述,不附加任何额外条款或条件。
依赖项
~295–750KB
~18K SLoC