15 breaking releases

new 0.17.0 May 18, 2024
0.15.0 May 18, 2024
0.13.0 Mar 26, 2024
0.2.0 Oct 28, 2023

#2 in #variadic

Download history 5/week @ 2024-02-09 16/week @ 2024-02-16 27/week @ 2024-02-23 494/week @ 2024-03-01 288/week @ 2024-03-08 650/week @ 2024-03-15 433/week @ 2024-03-22 73/week @ 2024-03-29 15/week @ 2024-04-05 25/week @ 2024-04-12 214/week @ 2024-04-19 7/week @ 2024-04-26 30/week @ 2024-05-03 3043/week @ 2024-05-10

3,302 downloads per month
Used in 46 crates (via derive_tools)

MIT license

23KB
276 lines

Module :: variadic_from

experimental rust-status docs.rs Open in Gitpod discord

The variadic from is designed to provide a way to implement the From-like traits for structs with a variable number of fields, allowing them to be constructed from tuples of different lengths or from individual arguments. This functionality is particularly useful for creating flexible constructors that enable different methods of instantiation for a struct. By automating the implementation of traits crate reduces boilerplate code and enhances code readability and maintainability.

Currently it support up to 3 arguments. If your structure has more than 3 fields derive generates nothing. Also it supports tuple conversion, allowing structs to be instantiated from tuples by leveraging the From and Into traits for seamless conversion.

Basic use-case.

This example demonstrates the use of the variadic_from macro to implement flexible constructors for a struct, allowing it to be instantiated from different numbers of arguments or tuples. It also showcases how to derive common traits like Debug, PartialEq, Default, and VariadicFrom for the struct.

#[ cfg( not( all(feature = "enabled", feature = "type_variadic_from", feature = "derive_variadic_from" ) ) ) ]
fn main(){}
#[ cfg( all( feature = "enabled", feature = "type_variadic_from", feature = "derive_variadic_from" ) )]
fn main()
{
  use variadic_from::exposed::*;

  // Define a struct `MyStruct` with fields `a` and `b`.
  // The struct derives common traits like `Debug`, `PartialEq`, `Default`, and `VariadicFrom`.
  #[ derive( Debug, PartialEq, Default, VariadicFrom ) ]
  // Use `#[ debug ]` to expand and debug generate code.
  // #[ debug ]
  struct MyStruct
  {
    a : i32,
    b : i32,
  }

  // Implement the `From1` trait for `MyStruct`, which allows constructing a `MyStruct` instance
  // from a single `i32` value by assigning it to both `a` and `b` fields.

  impl From1< i32 > for MyStruct
  {
    fn from1( a : i32 ) -> Self { Self { a, b : a } }
  }

  let got : MyStruct = from!();
  let exp = MyStruct { a : 0, b : 0 };
  assert_eq!( got, exp );

  let got : MyStruct = from!( 13 );
  let exp = MyStruct { a : 13, b : 13 };
  assert_eq!( got, exp );

  let got : MyStruct = from!( 13, 14 );
  let exp = MyStruct { a : 13, b : 14 };
  assert_eq!( got, exp );

  dbg!( exp );
  //> MyStruct {
  //>   a: 13,
  //>   b: 14,
  //> }

}
The code above will be expanded to this
#[ cfg( not( all(feature = "enabled", feature = "type_variadic_from" ) ) ) ]
fn main(){}
#[ cfg( all( feature = "enabled", feature = "type_variadic_from" ) )]
fn main()
{
  use variadic_from::exposed::*;

  // Define a struct `MyStruct` with fields `a` and `b`.
  // The struct derives common traits like `Debug`, `PartialEq`, `Default`
  // `VariadicFrom` defined manually.
  #[ derive( Debug, PartialEq, Default ) ]
  struct MyStruct
  {
    a : i32,
    b : i32,
  }

  // Implement the `From1` trait for `MyStruct`, which allows constructing a `MyStruct` instance
  // from a single `i32` value by assigning it to both `a` and `b` fields.
  impl From1< i32 > for MyStruct
  {
    fn from1( a : i32 ) -> Self { Self { a, b : a } }
  }

  // == begin of generated

  impl From2< i32, i32 > for MyStruct
  {
    fn from2( a : i32, b : i32 ) -> Self { Self{ a : a, b : b } }
  }

  impl From< ( i32, i32 ) > for MyStruct
  {
    #[ inline( always ) ]
    fn from( ( a, b ) : ( i32, i32 ) ) -> Self
    {
      Self::from2( a, b )
    }
  }

  // == end of generated

  let got : MyStruct = from!();
  let exp = MyStruct { a : 0, b : 0 };
  assert_eq!( got, exp );

  let got : MyStruct = from!( 13 );
  let exp = MyStruct { a : 13, b : 13 };
  assert_eq!( got, exp );

  let got : MyStruct = from!( 13, 14 );
  let exp = MyStruct { a : 13, b : 14 };
  assert_eq!( got, exp );

  dbg!( exp );
  //> MyStruct {
  //>   a: 13,
  //>   b: 14,
  //> }

}

Try out cargo run --example variadic_from_trivial.
See code.

To add to your project

cargo add variadic_from

Try out from the repository

git clone https://github.com/Wandalen/wTools
cd wTools
cargo run --example variadic_from_trivial

Dependencies

~1–1.4MB
~31K SLoC