Expand description

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 struct, with the following:

  1. An associated predicate function is_valid that returns true if the string provided would be a valid value for the type.
  2. This type derives implementations of Clone, Debug, PartialEq, PartialOrd, Eq, Ord, and Hash.
  3. An implementation of Display for T that simply returns the inner value.
  4. An implementation of From<T> for String.
  5. An implementation of Deref for T with the target type str.
  6. 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 with the macro is_valid_newstring 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;
use std::ops::Deref;

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")
);

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.

Macros

This macro takes a new type identifier and a parse function to produce a new type. The parse function must take the form fn(&str) -> Result<String, Err>, this is called from within the FromStr::from_str function to actually parse the string, and in doing so potentially returning an altered form if necessary.
This macro takes a new type identifier and a predicate function to produce a new type. The predicate is called by T::is_valid and is then used in the implementation of FromStr to determine whether to return a new instance or error. As this is simply a boolean value and does not differentiate between reasons for invalidity the error type for FromStr is always ().
This macro adds an implementation of the constructor new_unchecked which creates a new instance without any validity checking.
This macro takes a string that contains a regular expression will construct a new validity predicate that may be used by the is_valid_newstring macro. An optional second parameter provides a name for the new predicate function, overriding the default is_valid.