Skip to content

Commit

Permalink
Update documentation with section about const_fn
Browse files Browse the repository at this point in the history
  • Loading branch information
greyblake committed Jan 4, 2025
1 parent 423987f commit 1310fbb
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 0 deletions.
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Nutype is a proc macro that allows adding extra constraints like _sanitization_
* [Quick start](#quick-start)
* [Inner types](#inner-types) ([String](#string) | [Integer](#integer) | [Float](#float) | [Other](#other-inner-types-and-generics))
* [Custom](#custom-sanitizers) ([sanitizers](#custom-sanitizers) | [validators](#custom-validators) | [errors](#custom-validation-with-a-custom-error-type))
* [Constants](#constants)
* [Recipes](#recipes)
* [Breaking constraints with new_unchecked](#breaking-constraints-with-new_unchecked)
* [Feature Flags](#feature-flags)
Expand Down Expand Up @@ -345,6 +346,46 @@ struct Name(String);

It's important to ensure that the type specified in the `error` attribute matches the error type returned by the validation function.

## Constants

You can mark a type with the `const_fn` flag. In that case, its `new` and `try_new` functions will be declared as `const`:

```rust
#[nutype(
const_fn,
derive(Debug),
validate(greater_or_equal = -273.15),
)]
pub struct Celsius(f64);
```

Since `Result::unwrap()` is not allowed in `const` contexts, we must manually handle the `Result` when creating constants. Any attempt to instantiate an invalid `Celsius` at compile time will trigger a compilation error:

```rust
const FREEZING_POINT: Celsius = match Celsius::try_new(0.0) {
Ok(value) => value,
Err(_) => panic!("Invalid value"),
};
```

Alternatively, you can use a helper macro like this:

```rust
macro_rules! nutype_const {
($name:ident, $ty:ty, $value:expr) => {
const $name: $ty = match <$ty>::try_new($value) {
Ok(value) => value,
Err(_) => panic!("Invalid value"),
};
};
}

nutype_const!(WATER_BOILING_POINT, Celsius, 100.0);
```

Note that `const` works only for stack allocated types.
If you are dealing with a heap allocated type (e.g. `String`) you should consider using `static` with [`LazyLock`](https://doc.rust-lang.org/beta/std/sync/struct.LazyLock.html).

## Recipes

### Derive `Default`
Expand Down
43 changes: 43 additions & 0 deletions nutype/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,49 @@
//!
//! It's important to ensure that the type specified in the `error` attribute matches the error type returned by the validation function.
//!
//!
//! ## Constants
//!
//! You can mark a type with the `const_fn` flag. In that case, its `new` and `try_new` functions will be declared as `const`:
//!
//! ```
//! use nutype::nutype;
//!
//! #[nutype(
//! const_fn,
//! derive(Debug),
//! validate(greater_or_equal = -273.15),
//! )]
//! pub struct Celsius(f64);
//!
//! // Since `Result::unwrap()` is not allowed in `const` contexts,
//! // we must manually handle the `Result` when creating constants.
//! // Any attempt to instantiate an invalid `Celsius` at compile time
//! // will trigger a compilation error:
//! const FREEZING_POINT: Celsius = match Celsius::try_new(0.0) {
//! Ok(value) => value,
//! Err(_) => panic!("Invalid value"),
//! };
//!
//! assert_eq!(FREEZING_POINT.into_inner(), 0.0);
//!
//! // Alternatively, you can use a helper macro like this:
//! macro_rules! nutype_const {
//! ($name:ident, $ty:ty, $value:expr) => {
//! const $name: $ty = match <$ty>::try_new($value) {
//! Ok(value) => value,
//! Err(_) => panic!("Invalid value"),
//! };
//! };
//! }
//!
//! nutype_const!(WATER_BOILING_POINT, Celsius, 100.0);
//!
//! assert_eq!(WATER_BOILING_POINT.into_inner(), 100.0);
//! ```
//! Note that `const` works only for stack allocated types.
//! If you are dealing with a heap allocated type (e.g. `String`) you should consider using `static` with [`LazyLock`](https://doc.rust-lang.org/beta/std/sync/struct.LazyLock.html).
//!
//! ## Recipes
//!
//! ### Derive `Default`
Expand Down

0 comments on commit 1310fbb

Please sign in to comment.