Variables with the desired range

Hello,
Is it possible to define a variable with the desired range? For example, the u8 range is from 0 to 255.

Thank you.

Could you be a little bit more specific? In your example, do you want to further restrict a u8 value to a sub-range of u8 or what is your goal exactly?

I think hack3rcon is thinking of automatically restricting a type to a certain range. The 0-255 is hardware specific due to the size of the variable in memory, but maybe it would be beneficial to be able to define software restricted types. e.g. type temperature = f64 in range (-273.15..). Restricting the variables of the temperature type to real numbers between -273.15 Celsius but open it up to however big f64 can hold . I know that Ada has a feature like this, but I do not think it exists in Rust (Would be nice though).

Or maybe a type selector similar to Fortran's SELECTED_REAL_KIND(P,R) or SELECTED_INT_KIND(R) which return the smallest type to be able to hold a number specified by P and R.

This has been discussed many times and already a long time ago: https://github.com/rust-lang/rfcs/issues/671.

As far as I know, today we have the non-zero types like NonZeroU32 in std::num - Rust that can be used when your range excludes zero which allows for certain memory space optimizations.

You could define an enum enum V { Z0 = 0, P1 = 1, P2 = 2 } for the range 0..=2 or just write a struct V(u8) (newtype pattern) that can help statically guarantee that any value contained within V is within the desired range.

1 Like

If you want to read more or find more recent discussions, search for "pattern types" and/or go link-chasing from here.

It's not a part of Rust today.

1 Like

You could use some generic magic to check your numbers at compile time, like this:

struct Hi<const LOW: u8, const HIGH: u8>(u8);

impl<const L: u8, const H: u8> Hi<L, H> {
	fn new<const INPUT: u8>() -> u8 {
		if L <= INPUT && INPUT <= H {
			INPUT
		} else {
			panic!("NUMBER {INPUT} ISN'T IN THE {L} .. {H} RANGE")
		}
	}
}

fn main() {
	let hi = Hi::<0, 4>::new::<2>(); // This will not panic
	let hi = Hi::<0, 4>::new::<65>(); // This will panic
}

Just an interesting experiment, but if you know what you are doing and decide to implement this, I'd recommend putting it similar to this:

macro_rules! new_hi {
	(between $l: literal and $h: literal; $inner: literal) => {
		Hi::<$l, $h>::new::<$inner>()
	};
}

Thanks to compiler optimizations and compile-time magic, it doesn't take any runtime to initialize from a constant number.

1 Like

If runtime validation is good enough, @greyblake recently released nutype 0.3 (thread), and you can do:

#[nutype(validate(min = 1, max = 10))]
struct SmallNumber(u8);
2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.