1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
//! Integers that are constrained within inclusive ranges.
//!
//! `Constrained` types are represented simply as primitive integers, but their
//! values will **always** be contained by inclusive range bounds. The range is
//! defined at compile time, by assigning values to appropriate const generic
//! parameters. Constrained types provide fallible APIs for construction and
//! value assignment, they also implement wrapping, saturating, overflowing
//! and checked arithmetic operations for the range boundaries. See each desired
//! type documentation for more information.
//!
//! The `constrained_int` crate relies on the [`const_guards`] crate to define
//! compile time constraints, which itself uses the incomplete [`generic_const_exprs`]
//! feature. Therefore, this crate can only be compiled with nightly and, more
//! importantly, must be considered as an **experimental** crate only.
//!
//! This crate is `no_std` by default. See features section for more information.
//!
//! ## Example
//!
//! ```
//! use constrained_int::i8::{ConstrainedI8, ConstrainedI8Error};
//!
//! // Lower bound = -5, upper bound = 10, default = -1.
//! type Constrained = ConstrainedI8<-5, 10, -1>;
//! type ConstrainedError = ConstrainedI8Error<-5, 10>;
//!
//! // Gets user defined default value.
//! let mut constrained = Constrained::default();
//! assert_eq!(constrained.get(), -1);
//!
//! // Sets within inclusive range, succeeds.
//! constrained.set(-5)?;
//! assert_eq!(constrained.get(), -5);
//!
//! // Below lower bound.
//! assert_eq!(constrained.checked_sub(1), None);
//! assert_eq!(constrained.get(), -5);
//!
//! // Saturates at upper bound.
//! constrained = constrained.saturating_add(100);
//! assert_eq!(constrained.get(), 10);
//!
//! // Sets out of bound, fails.
//! assert!(constrained.set(11).is_err());
//!
//! // Wraps around the upper bound.
//! constrained = constrained.wrapping_add(1);
//! assert_eq!(constrained.get(), -5);
//! # Ok::<(), constrained_int::i8::ConstrainedI8Error<-5, 10>>(())
//! ```
//!
//! ## Safety
//!
//! This crate uses `#![forbid(unsafe_code)]` to ensure everything is implemented
//! in 100% safe Rust.
//!
//! ## Feature flags
//!
//! This crate does not provide any default features. The features that can be
//! enabled are: `std` and `serde`.
//!
//! ### std
//!
//! This crate does not link against the standard library by default, so it is
//! suitable for `no_std` environments. It does provide a `std` feature though,
//! that enables the standard library as a dependency. By enabling this crate's
//! `std` feature, these additional features are provided:
//! - All crate's error types will implement the `std::error::Error` trait.
//! If users already are importing the standard library on their crate, enabling
//! `std` feature comes at no additional cost.
//!
//! ### serde
//!
//! The `serde` feature implements [`serde`]'s `Serialize` and `Deserialize` traits
//! for `Wrapping`, `Saturating` and all `Constrained` types. Note that construction
//! constraints for the const generic parameters are checked at runtime when values
//! are deserialized to any of the `Constrained` types. See each desired type
//! documentation for more information about these constraints.
//!
//! [`generic_const_exprs`]: https://github.com/rust-lang/rust/issues/76560
//! [`serde`]: https://docs.rs/serde/latest/serde/
// No raw pointers here, maybe in another castle.
//
// The `std` feature will import `std` as a dependency.
//
// The `const_guards` dependency relies on `generic_const_exprs`.
// Tracking issue for `generic_const_exprs`:
// https://github.com/rust-lang/rust/issues/76560
//
// Tracking issue for `const_trait_impl`:
// https://github.com/rust-lang/rust/issues/67792
//
// Tracking issue for `const_mut_refs`:
// https://github.com/rust-lang/rust/issues/57349
//
// Tracking issue for `doc_cfg` and `doc_auto_cfg`feature:
// https://github.com/rust-lang/rust/issues/43781.
//
// rustdoc lints.
// Import:
// - `constrained_uint_def_impl!`.
// - `constrained_int_def_impl!`.
// - `forward_ref_binop!`.
// Required:
// - `forward_ref_binop!`.
// - `forward_ref_op_assign!`.
pub use ;
// Define mods, containers, errors, tests and impls for unsigned integers with
// default values for doc examples.
//
// Format:
// { uint, sint, uint_mod, sint_mod, TypeName, ErrorName, MinErrorName, MaxErrorName },+
constrained_uint_def_impl!
// Define mods, containers, errors, tests and impls for signed integers with
// default values for doc examples.
//
// Format:
// { sint, uint, sint_mod, uint_mod, TypeName, ErrorName, MinErrorName, MaxErrorName },+
constrained_int_def_impl!