Easy-to-use optional function arguments for Rust

Overview

OptArgs: Optional arguments for Rust functions

Enable optional arguments for any function:

#[optargs::optfn]
pub fn plot(
    x: Vec<i32>,
    y: Option<Vec<i32>>,
    title: Option<&str>,
    xlabel: Option<&str>,
    ylabel: Option<&str>,
    legend: Option<bool>
) {}

// can now call it with optional arguments
plot!(
    x: vec![1,2,3], 
    y: vec![1,2,3], 
    title: "Awesome plot", 
    xlabel: "x axis", 
    ylabel: "y axis"
);

...or struct:

#[derive(optargs::OptStruct)]
pub struct Scatter {
    x: Vec<i32>,
    y: Option<Vec<i32>>,
    title: Option<&str>,
    xlabel: Option<&str>,
    ylabel: Option<&str>,
    legend: Option<bool>
}
impl Scatter {
    fn plot(self) {/* custom impl that references self */}
}

// Call it
Scatter!{ x: vec![1,2,3], y: vec![1,2,3] }.plot()

This crate is especially useful for cleaning up builder-heavy codebases and making library APIs more ergonomic. It also integrates well with Rust-Analyzer and doesn't generate heavy compile times.


This crate adds two macros to make it easy to add optional arguments to functions.

  • #[optargs] - derive a macro_rules to call a function with optional arguments.
  • #[derive(OptStruct)] - derive a typed-builder builder for a struct with optional fields.

This crate takes advantage of the recent const_generics in Rust stable (1.51), so our MSRV is 1.51.

Of note:

  • All optional arguments will default to none. We currently don't provide a custom default (accepting PRs if anyone wants!).
  • All optional arguments must come after required arguments.
  • Unnamed positional arguments must be in the correct position.
  • All arguments can be required, but now you get to name them.
  • Traditional macro_rules scoping applies IE you can't use the macro before function declaration. However, they are exported with macro_export, so you can use them anywhere with crate::$MACRO. Currently, there's no way to disable this, so you can't have two functions with the same name. If this becomes a problem, we'll gladly accept a PR.

How it works:

OptArgs uses const generics to ensure compile-time correctness. I've taken the liberty of expanding and humanizing the macros in the reference examples.

In essence, we encode the state of required parameters into a ZST with const parameters. When each required parameter is added, we flip the const parameter from false to true. Only when all the required parameters are entered, then can we proceed with calling the original function.

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

You might also like...
Rust macro to use a match-like syntax as a elegant alternative to nesting if-else statement

cond Rust macro to use a match-like syntax as an elegant alternative to many if-else statements. I got the idea from empty Go switch statements. I tho

very cool esoteric language pls use

okfrick has one memory pointer has less than 5 characters hopefully works well is turing complete (possibly) + - increase memeory pointer value ( - st

 Achieve it! How you ask? Well, it's pretty simple; just use greatness!
Achieve it! How you ask? Well, it's pretty simple; just use greatness!

Greatness! Achieve it! How you ask? Well, it's pretty simple; just use greatness! Disclaimer I do not believe that greatness is the best. It fits a me

use variant nesting information to flter overlapping sites from vg deconstruct output

vcfbub popping bubbles in vg deconstruct VCFs overview The VCF output produced by a command like vg deconstruct -e -a -H '#' ... includes information

Use enum to predicate something, support | and & operator.
Use enum to predicate something, support | and & operator.

Predicate Use enum to predicate something. Just need to implement Predicate Trait with predicate-macros crate, support | and & operator. Don't impleme

A minimal RedDSA implementation for use in Zebra and zcashd.

A minimal RedDSA implementation for use in Zcash. Two specializations of RedDSA are used in Zcash: RedJubjub and RedPallas. For each of these, two par

little brother of gnu-copypasta-maker To compile, use make.

UWU Maker little brother of gnu-copypasta-maker To compile, use make. To install, use sudo make install or if you are root make install To uninstall,

Here are a few cargo-generate templates for use when creating bevy applications
Here are a few cargo-generate templates for use when creating bevy applications

Bevy-template-rs Here are a few cargo-generate templates for use when creating bevy applications. Templates Game This is a template for starting a new

Default implementation of the Wayland protocol for use with wl

Wayland An implementation of core Wayland interfaces and convenience functions for accelerating the development of Wayland clients and servers using t

Owner
Jonathan Kelley
Systems engineer. Passionate about complex systems, data, and business.
Jonathan Kelley
MeiliSearch is a powerful, fast, open-source, easy to use and deploy search engine

MeiliSearch is a powerful, fast, open-source, easy to use and deploy search engine. Both searching and indexing are highly customizable. Features such as typo-tolerance, filters, and synonyms are provided out-of-the-box. For more information about features go to our documentation.

MeiliSearch 31.6k Dec 30, 2022
Simplistic complier~virtual-machine that transforms AST into a Rust function, with basic type checking

rast-jit-vm rast-jit-vm is a simplistic, proof-of-concept~ish compiler / virtual machine that transforms syntax tree into a Rust function, type-checki

Patryk Wychowaniec 4 Oct 23, 2022
Lambda function to handle Bitbucket webhook payloads, extract relevant information and send notifications to Microsoft Teams

PR-Bot Lambda function to handle Bitbucket webhook payloads, extract relevant information, and send notifications to Microsoft Teams, saving you time

Irine 14 Sep 26, 2023
Help project managers and project owners with easy-to-understand views of github issue dependencies.

Help project managers and project owners with easy-to-understand views of github issue dependencies.

nasa 56 Dec 15, 2022
Macros to make writing proc-macro crates easy

proc-easy Macros to make writing proc-macro crates easy. This crate provides mainly macros and supporting types and traits to reduce amount of boilerp

Zakarum 7 Jan 1, 2023
Use explicit container types with Scrypto! Leverage the Rust compiler's type checking to increase security and productivity when developing Radix blueprints.

Scrypto Static Types Use explicit container types with Scrypto! Leverage the Rust compiler's type checking to increase security and productivity when

null 7 Aug 5, 2022
A flexible, simple to use, immutable, clone-efficient String replacement for Rust

flexstr A flexible, simple to use, immutable, clone-efficient String replacement for Rust Overview Rust is great, but it's String type is optimized as

Scott Meeuwsen 119 Dec 12, 2022
The easiest way to use BotiCord API in Rust

The easiest way to use BotiCord API in Rust · Docs Usage [dependencies]

BotiCord 6 Feb 14, 2022
Powerfull Discord Raid Bot written in Rust, use VPN / Proxy because creating 200 channels in 10s Will ratelimit you.

Harakiri-Rust This the first Discord Raid Bot made in RustLang I recommend you use with a VPN or a Proxy to evade Discord Ratelimit. If bot doesn't st

Marco 6 May 1, 2023
💡 Use the right package manager by rust

n ?? Use the right package manager by rust ?? Inspired by ni Why ni is nice , but ni is based on Node. it is difficult to collaborate well with node v

SHEIN 3 Jul 24, 2023