Crates.io | intuple |
lib.rs | intuple |
version | 0.2.0 |
source | src |
created_at | 2022-09-25 23:59:53.642482 |
updated_at | 2023-11-14 11:55:50.375693 |
description | Convert structs and enums into tuples (of refs) and back - recursive, ignore fields |
homepage | |
repository | https://github.com/dekirisu/intuple/ |
max_upload_size | |
id | 673866 |
size | 41,382 |
ð convert a struct into a tuple and back
ðĶ convert an enum into a tuple and back
ðĶĒ get a tuple of (mut) references of fields of a struct
ð get a tuple of (mut) references of fields of an enum
ðĶĨ ignore specific fields
ðĶ do it all recursively
ð add intuple to the dependencies in the Cargo.toml
:
[dependencies]
intuple = "0.2"
ðĶ use/import everything into rust:
use intuple::*;
ðĶ multiple ways to convert:
#[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;
}
ðĶ access the resulting tuple types through a qualified path:
#[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
}
ðĶĨ ignore specific fields with #[igno]
/#[ignore]
ðŧ or #[intuple(igno)]
/#[intuple(ignore)]
ðž ignored fields need to implement Default while converting to a struct
#[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)
}
ðĶ convert recursively with #[recursive]
/#[rcsv]
ðĶ or #[intuple(rcsv)]
/#[intuple(recursive)]
ðž recursive fields need to derive 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)
}
ðĶ recursion also works with .as_tuple_ref()
and 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)
}
ð converting enums to tuples isn't as straight forward as structs, therefore two methods are implemented!
ð using Intuple
- no additional enums or structs are generated
ðĒ field tuples are wrapped in an Option<>
, which are inside another tuple
ðĶ the outer tuple has as many fields as there are enum variants
ð the required None
variant will convert to (None,None,None,...)
ð any other variant will occupy a slot, depending on its position (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)
}
ð using IntupleEnum
- three additional enums will be generated:
ð {EnumName}Intuple
, {EnumName}IntupleRef
and {EnumName}IntupleRefMut
ðĶ each of those will use the original variant names and contain a tuple
ð to set derives for them, use #[intuple(derive(...))]
â to use them recursivly ANYWHERE, use #[recursive_enum]
or #[rcsve]
ðĶĒ .into()
/.from(..)
are implemented, but the custom methods change to:
ð .from_tuple_enum(..)
, .into_tuple_enum()
, .as_tuple_enum_ref()
and .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))
}
ðĶ You could use serde
without implementing Serialize/Deserialize
ð This only works with the positional enum tuples!
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
}
ðĶ Changelog
ðą GitHub
ðū Discord Server