Skip to content

Commit ca4a93c

Browse files
committed
rust: types: add little-endian type
It allows us to read/write data in little-endian format. Compared to just using the correctly-sized integer type, it has the advantage of forcing users to convert to and from little endian format (which will be no-ops in little-endian architectures). Signed-off-by: Wedson Almeida Filho <[email protected]>
1 parent c7d0fb2 commit ca4a93c

File tree

1 file changed

+68
-0
lines changed

1 file changed

+68
-0
lines changed

rust/kernel/types.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,3 +395,71 @@ pub enum Either<L, R> {
395395
/// Constructs an instance of [`Either`] containing a value of type `R`.
396396
Right(R),
397397
}
398+
399+
/// A type that can be represented in little-endian bytes.
400+
pub trait LittleEndian {
401+
/// Converts from native to little-endian encoding.
402+
fn to_le(self) -> Self;
403+
404+
/// Converts from little-endian to the CPU's encoding.
405+
fn to_cpu(self) -> Self;
406+
}
407+
408+
macro_rules! define_le {
409+
($($t:ty),+) => {
410+
$(
411+
impl LittleEndian for $t {
412+
fn to_le(self) -> Self {
413+
Self::to_le(self)
414+
}
415+
416+
fn to_cpu(self) -> Self {
417+
Self::from_le(self)
418+
}
419+
}
420+
)*
421+
};
422+
}
423+
424+
define_le!(u8, u16, u32, u64, i8, i16, i32, i64);
425+
426+
/// A little-endian representation of `T`.
427+
///
428+
/// # Examples
429+
///
430+
/// ```
431+
/// use kernel::types::LE;
432+
///
433+
/// struct Example {
434+
/// a: LE<u32>,
435+
/// b: LE<u32>,
436+
/// }
437+
///
438+
/// fn new(x: u32, y: u32) -> Example {
439+
/// Example {
440+
/// a: x.into(), // Converts to LE.
441+
/// b: y.into(), // Converts to LE.
442+
/// }
443+
/// }
444+
///
445+
/// fn sum(e: &Example) -> u32 {
446+
/// // `value` extracts the value in cpu representation.
447+
/// e.a.value() + e.b.value()
448+
/// }
449+
/// ```
450+
#[derive(Clone, Copy)]
451+
#[repr(transparent)]
452+
pub struct LE<T: LittleEndian + Copy>(T);
453+
454+
impl<T: LittleEndian + Copy> LE<T> {
455+
/// Returns the native-endian value.
456+
pub fn value(&self) -> T {
457+
self.0.to_cpu()
458+
}
459+
}
460+
461+
impl<T: LittleEndian + Copy> core::convert::From<T> for LE<T> {
462+
fn from(value: T) -> LE<T> {
463+
LE(value.to_le())
464+
}
465+
}

0 commit comments

Comments
 (0)