4 releases
0.0.4 | Jul 30, 2024 |
---|---|
0.0.3 | Jun 16, 2024 |
0.0.2 | Nov 26, 2021 |
0.0.1 | Nov 26, 2021 |
#876 in Procedural macros
258 downloads per month
Used in bgmtv
46KB
828 lines
utility types
This crate use proc-macro to realize several utility types of Typescript in Rust.
macro | Typescript Utility Type |
---|---|
[Partial] | Partial<Type> |
[Pick] | Pick<Type, Keys> |
[Omit] | Omit<Type, Keys> |
[Extract] | Extract<Type, Union> |
[Exclude] | Exclude<UnionType, ExcludedMembers> |
Example
Here is an example of how to use this crate.
use utility_types::{Omit, Partial, Pick, Required};
#[derive(Clone, Partial, Required, Pick, Omit)]
#[partial(ident = PartialFoo, derive(Debug, PartialEq), forward_attrs())]
#[required(ident = RequiredFoo, derive(Debug, PartialEq), forward_attrs())]
#[pick(arg(ident = PickAB, fields(a, b), derive(Debug, PartialEq)), forward_attrs())]
#[omit(arg(ident = OmitCD, fields(c, d), derive(Debug, PartialEq)), forward_attrs())]
pub struct Foo {
a: u8,
b: Option<u8>,
c: Option<Vec<u8>>,
}
The above code will generate the following code.
#[derive(Debug, PartialEq)]
pub struct PartialFoo {
a: Option<u8>,
b: Option<Option<u8>>,
c: Option<Option<Vec<u8>>>,
}
#[derive(Debug, PartialEq)]
pub struct RequiredFoo {
a: u8,
b: u8,
c: Vec<u8>,
}
#[derive(Debug, PartialEq)]
pub struct PickAB {
a: u8,
b: Option<u8>,
}
#[derive(Debug, PartialEq)]
pub struct OmitCD {
a: u8,
b: Option<u8>,
}
Some useful traits are also generated:
From<Foo>
forPartialFoo
,PickAB
,OmitCD
From<PartialFoo>
forFoo
Forwarding Attributes
To use this crate with other crates that need attributes, you can use the forward_attrs
attribute to control which attributes are forwarded to the generated struct or enum.
use serde::{Deserialize, Serialize};
use utility_types::Omit;
#[derive(Debug, PartialEq, Serialize, Deserialize, Omit)]
#[omit(
arg(
ident = OmitCD,
fields(c, d),
derive(Debug, PartialEq, Serialize, Deserialize),
forward_attrs(serde)
)
)]
#[serde(rename_all = "UPPERCASE")]
pub struct Foo {
a: u8,
b: Option<u8>,
c: Option<Vec<u8>>,
}
let omit_cd: OmitCD = serde_json::from_str(r#"{"A": 1, "B": 2}"#).unwrap();
assert_eq!(omit_cd, OmitCD { a: 1, b: Some(2) });
The behavior of the forward_attrs
attribute is as follows:
- If not provided, all attributes are forwarded by default.
- If provided with a list of attributes, only the specified attributes are forwarded.
- For example,
forward_attrs(doc, serde)
will forward onlydoc
andserde
. - If provided with only
*
(forward_attrs(*)
), all attributes are forwarded. - If provided with an empty list (
forward_attrs()
), no attributes are forwarded.
- For example,
- If provided with a list inside
not()
, all attributes except the specified attributes are forwarded.- For example,
forward_attrs(not(serde))
will forward all attributes exceptserde
.
- For example,
Known Issue
Currently I don't analyze which generic is used in the generated struct or enum. So rustc will complain if the field with generic is not included in the generated struct or enum.
Dependencies
~0.6–1MB
~23K SLoC