starnix_uapi/
user_value.rs1use std::ops::Range;
6use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
7
8#[derive(Debug, Clone, Copy, Eq, PartialEq, IntoBytes, KnownLayout, FromBytes, Immutable)]
14#[repr(transparent)]
15pub struct UserValue<T>(T);
16
17impl<T: Copy + Eq + IntoBytes + FromBytes + Immutable> UserValue<T> {
18 pub fn from_raw(raw: T) -> Self {
20 Self(raw)
21 }
22
23 pub fn raw(&self) -> T {
25 self.0
26 }
27
28 pub fn try_into<U: TryFrom<T>>(self) -> Result<U, <U as TryFrom<T>>::Error> {
30 U::try_from(self.0)
31 }
32}
33
34impl<T: Copy + PartialOrd> UserValue<T> {
35 pub fn validate(&self, range: Range<T>) -> Option<T> {
37 if range.contains(&self.0) { Some(self.0) } else { None }
38 }
39}
40
41macro_rules! impl_try_from_user_value {
43 {
44 $(
45 $source:ty => $target:ty
46 ),+
47 $(,)?
48 } => {
49 $(
50 impl TryFrom<$source> for UserValue<$target> {
51 type Error = ();
52
53 fn try_from(u: $source) -> Result<Self, Self::Error> {
54 let t = u.try_into().map_err(|_| ())?;
55 Ok(Self::from_raw(t))
56 }
57 }
58 )*
59 }
60}
61
62impl_try_from_user_value! {
63 u32 => usize,
64 u64 => usize,
65 usize => u32,
66 usize => u64,
67}
68
69impl<T: Copy + Eq + IntoBytes + FromBytes + Immutable> From<T> for UserValue<T> {
70 fn from(value: T) -> Self {
71 Self::from_raw(value)
72 }
73}
74
75impl<T: PartialEq<T> + Copy + Eq + IntoBytes + FromBytes + Immutable> PartialEq<T>
76 for UserValue<T>
77{
78 fn eq(&self, other: &T) -> bool {
79 self.0 == *other
80 }
81}