5 unstable releases
| 0.3.0 | Oct 22, 2025 |
|---|---|
| 0.2.0 | Oct 10, 2022 |
| 0.1.2 | May 14, 2021 |
| 0.1.1 | Apr 16, 2021 |
| 0.1.0 | Apr 16, 2021 |
#530 in Rust patterns
86 downloads per month
Used in cargo_tsgen
19KB
147 lines
Crate newstr
Simple macros for declaring String-base new types.
This crate provides simple macros that generate String based new types. The
two primary macros implement the validity rules for the new type by either 1)
providing a predicate that is used by the is_valid associated function, or 2)
providing a function to parse and return a string which is then called by
FromStr::from_str.
Both of these methods produce a new type, with the following:
- An associated predicate function
is_validthat returnstrueif the string provided would be a valid value for the type. - This type derives implementations of
Clone,Debug,PartialEq,PartialOrd,Eq,Ord, andHash. - An implementation of
DisplayforTthat simply returns the inner value. - An implementation of
From<T>forString. - An implementation of
AsRefforTwith the target typestr. - An implementation of
DerefforTwith the target typestr. - An implementation of
FromStr.
Additional user-required traits can also be added to the macro to be derived by the implementation.
Example
The following example constructs a new string type that implements an
Identifier value. This value must be ASCII, alphanumeric, the '_' character
and must not be empty.
use std::fmt::{Display, Formatter};
use std::str::FromStr;
fn is_identifier_value(s: &str) -> bool {
!s.is_empty() && s.chars().all(|c| c.is_ascii_alphanumeric() || c == '_')
}
is_valid_newstring!(Identifier, is_identifier_value);
assert!(!Identifier::is_valid(""));
assert!(!Identifier::is_valid("hi!"));
assert!(!Identifier::is_valid("hello world"));
assert!(!Identifier::is_valid("9.99"));
assert_eq!(
Identifier::from_str("hi").unwrap().to_string(),
String::from("hi")
);
assert_eq!(
Identifier::from_str("hello_world").unwrap().to_string(),
String::from("hello_world")
);
The macro new_unchecked will add a constructor to the type that allows a
trusted client to bypass the validity checks.
new_unchecked!(pub(crate) Identifier);
assert_eq!(
Identifier::from_str("hi").unwrap(),
Identifier::new_unchecked("hi")
);
Dependencies
In the example above you can see the necessary use-statements for the trait
implementations the macros generate. Unless you use regex_is_valid there are
no crate dependencies; if you do you will need to add lazy_static and regex
dependencies.
Changes
Version 0.3.0
- Feature: allow visibility on all macros so private types can be created. However, this is a breaking change as public types now need explicit visibility.
- Feature: moved from the
lazy_staticcrate to usestd::sync::LazyLockto remove a client dependency.
Version 0.2.0
- Changes to the macro API;
- use
;instead of,to separate the additional derive macros, - use full paths inside all macros, no need for the
use_requiredmacro any more, - clients will need to import any trait they then use such as
FromStr.
- use
- Added
new_uncheckedmacro for validity bypass.
Version 0.1.2
- Added additional, optional, parameter to both macros that allows additional
traits to be added to the
deriveattribute on the generated struct. * Refactored the macros to reduce repetition. * Added some additional tests.
Version 0.1.1
- Added new
use_requiredmacro. - Removed unnecessary feature 'regex_is_valid', the build doesn't require this to avoid bloat.
- Made
lazy_staticandregexdev dependencies, if you don't use them, you don't need them. - Added dependency on
cargo-huskyfor Git cleanliness.
Version 0.1.0
- Initial version.